C++除了支持模板函数,还支持模板类。模板类的目的同样是将数据类型参数化。

声明模板类的语法为:

template<typename 数据类型参数 , typename 数据类型参数 , …> class 类名{
//TODO:
};

模板类和模板函数都是以 template 开头,后跟数据类型参数列表;数据类型参数不能为空,多个参数用逗号隔开。

一但声明了模板类,就可以用数据类型参数来声明类中的成员变量和成员函数。也就是说,原来使用C++内置类型(比如 int、float、char 等)的地方,都可以用类型参数来代替。

假如我们现在要定义一个类来表示坐标,要求坐标的数据类型可以是整数、小数和字符串,例如:

x = 、y =
x = 12.88、y = 129.65
x = "东京180度"、y = "北纬210度"

这个时候就可以使用模板类,请看下面的代码:

template<typename T1, typename T2>  //这里不能有分号
class Point{
private:
T1 x;
T2 y;
public:
Point(T1 _x, T2 _y): x(_x),y(_y){}
T1 getX();
void setX(T1 x);
T2 getY();
void setY(T2 y);
};

坐标 x 和 y 的数据类型不确定,借助模板类,就可以将数据类型参数化,否则就要定义多个类。

注意:模板头和类头是一个整体,可以换行,但是中间不能有分号。

上面是类的声明,还需要在类外定义成员函数。在类外定义成员函数时仍然需要带上模板头,语法为:

template<类型参数列表> 函数返回值类型 类名<类型参数列表>::函数名(参数列表){
//TODO:
}

下面对 Point 类的成员函数进行定义:

template<typename T1, typename T2>
T1 Point<T1, T2>::getX(){
return x;
}
template<typename T1, typename T2>
void Point<T1, T2>::setX(T1 x){
this->x = x;
}
template<typename T1, typename T2>
T2 Point<T1, T2>::getY(){
return y;
}
template<typename T1, typename T2>
void Point<T1, T2>::setY(T2 y){
this->y = y;
}

应当注意:在类外定义成员函数时,template 后面的类型参数列表要与类声明时的一致。

模板类的实例化

实例化模板类时,需要指明数据类型。例如:

Point<int, int> p1(, );
Point<int, float> p2(, 15.5);
Point<float, char*> p3(12.4, "东京180度");

与模板函数不同的是,模板类在实例化时必须显式地指明数据类型,编译器不能根据给定的数据推演出数据类型。下面的实例化代码是错误的:

Point p1(, );
Point p2(10.4, "东京180度");

至此,我们就可以定义模板类并实例化了。

将上面的代码整合起来,给出一个完整的示例:

#include <iostream>
using namespace std;
template<typename T1, typename T2> //这里不能有分号
class Point{
private:
T1 x;
T2 y;
public:
Point(T1 _x, T2 _y): x(_x),y(_y){}
T1 getX();
void setX(T1 x);
T2 getY();
void setY(T2 y);
};
template<typename T1, typename T2>
T1 Point<T1, T2>::getX(){
return x;
}
template<typename T1, typename T2>
void Point<T1, T2>::setX(T1 x){
this->x = x;
}
template<typename T1, typename T2>
T2 Point<T1, T2>::getY(){
return y;
}
template<typename T1, typename T2>
void Point<T1, T2>::setY(T2 y){
this->y = y;
}
int main(){
Point<int, int> p1(, );
cout<<"p1.x="<<p1.getX()<<", p1.y="<<p1.getY()<<endl; Point<int, char*> p2(, "东京180度");
cout<<"p2.x="<<p2.getX()<<", p2.y="<<p2.getY()<<endl; Point<float, float> *p = new Point<float, float>(10.6, 109.3);
cout<<"p->x="<<p->getX()<<", p->y="<<p->getY()<<endl;
return ;
}

注意代码第 44 行,当定义模板类的指针时,赋值号两边都需要指明具体的数据类型,且要保持一致。下面的写法是错误的:

//赋值号两边的数据类型不一致
Point<float, float> *p = new Point<float, int>(10.6, );
//赋值号右边没有指明数据类型
Point<float, float> *p = new Point(10.6, );

C++学习34 模板类的更多相关文章

  1. 学习C++ 模板类

    #include<iostream>#include<typeinfo>#include<cstring> using namespace std; class A ...

  2. C++学习三 模板类出错总结(Missing template arguments before 'L')

    一.模板类的说明 模板类有一个好处是可以放宽你输入的数据类型. 比如有这样的一个函数: int add(int x, int y) { return x+y; } 这个函数对于int类型的x,y才适合 ...

  3. 读书笔记_Effective_C++_条款四十三:学习处理模板化基类的名称

    背景是这样的,有两个不同的公司,然后想设计一个MessageSender,为这两个公司发送不同的消息,既支持明文发送SendClearText,也支持密文发送SendEncryptedText.一种思 ...

  4. C++学习笔记36:类模板

    类模板的目的 设计通用的类型式,以适应广泛的成员数据型式 类模板的定义格式 template<模板形式参数列表>class 类名称{...}; 原型:template<typenam ...

  5. C++ 模板学习 函数模板、类模板、迭代器模板

    使用模板能够极大到使得代码可重用. 记录一下,方便后续使用. 1. 函数模板,支持多种类型参数 #include <stdio.h> #include <math.h> //函 ...

  6. C++学习笔记(3)----类模板的static成员

    与任何其他类相同,类模板可以声明 static 成员: template <typename T> class Foo { public: static std::size_t count ...

  7. C++学习笔记(2)----类模板和友元

    当一个类包含一个友元声明时,类与友元各自是否是模板是相互无关的.如果一个类模板包含一个非模板友元,则友元被授权可以访问所有模板实例.如果友元自身是模板,类可以授权给所有友元模板实例,也可以只授权给特定 ...

  8. QCache 缓存(类似于map的模板类,逻辑意义上的缓存Cache,方便管理,默认类似于LRU的淘汰算法)

    最近在学习缓存方面的知识,了解了缓存(Cache)的基本概念,为什么要使用缓存,以及一些缓存算法(缓存替换),如LRU.LFU.ARC等等. 这些缓存算法的实现过程会使用一些基本的数据结构,如list ...

  9. C++:类模板与模板类

    6.3 类模板和模板类 所谓类模板,实际上是建立一个通用类,其数据成员.成员函数的返回值类型和形参类型不具体指定,用一个虚拟的类型来代表.使用类模板定义对象时,系统会实参的类型来取代类模板中虚拟类型从 ...

随机推荐

  1. jQuery.form.js使用

    jQuery.form.js是一个form插件,支持ajax表单提交和ajax文件上传. 下载地址 百度云:http://pan.baidu.com/s/1eQoYE46 360云:http://yu ...

  2. 二十四种设计模式:责任链模式(Chain of Responsibility Pattern)

    责任链模式(Chain of Responsibility Pattern) 介绍为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求.将这些对象连成一条链,并沿着这条链传递该请求,直 ...

  3. SqlServer数据库正在还原的解决办法

    1)管理器不会主动刷新,需要手工刷新一下才能看到最新状态(性能方面的考虑) 2)很少情况下,恢复进程被挂起了.这个时候假设你要恢复并且回到可访问状态,要执行:  RESTORE database   ...

  4. eclipse中java文件报错:The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files

    问题:The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class fi ...

  5. SQL2008安装自动退出

    一同事安装sql 2008 然后删除过,后来再也装不上了,安装SQL2008操作执行到安装支持文件的时候就会出现安装过程自动退出的现象. 网上很多人说需要卸载,我看原因不一定是这个,因为根本没有安装成 ...

  6. $(function(){})和$(document).ready(function(){})

    document.ready和onload的区别——JavaScript文档加载完成事件 页面加载完成有两种事件 一是ready,表示文档结构已经加载完成(不包含图片等非文字媒体文件) 二是onloa ...

  7. jQuery网页右侧固定层显示隐藏在线qq客服代码

    CSS代码: @charset "utf-8"; ;;} html,body{font-size:12px;font-family:"微软雅黑";outline ...

  8. LitDB文章

    阅读目录 1.LiteDB初步介绍 2.LiteDB使用基本案例 3.LiteDB的技术细节 4.资源其他 今天给大家介绍一个不错的小巧轻量级的NoSQL文件数据库LiteDB.本博客在2013年也介 ...

  9. Linux下编译Boost

    编译环境 操作系统: Red Hat Enterprise Linux Server release 5.4 64-bit 编译工具: gcc (GCC) 4.1.2 20080704 (Red Ha ...

  10. 23. Merge k Sorted Lists

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. = ...