C++学习34 模板类

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

声明模板类的语法为:

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

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

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

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

x = 10、y = 10
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(10, 20);
Point<int, float> p2(10, 15.5);
Point<float, char*> p3(12.4, "东京180度");

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

Point p1(10, 20);
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(10, 20);
    cout<<"p1.x="<<p1.getX()<<", p1.y="<<p1.getY()<<endl;

    Point<int, char*> p2(10, "东京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 0;
}

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

//赋值号两边的数据类型不一致
Point<float, float> *p = new Point<float, int>(10.6, 109);
//赋值号右边没有指明数据类型
Point<float, float> *p = new Point(10.6, 109);
时间: 2024-10-10 15:36:21

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

学习C++ 模板类

#include<iostream>#include<typeinfo>#include<cstring> using namespace std; class A{public: A(int x, int y) :m_x(x), m_y(y) { } int compare(void) { cout << "Type of m_x is" << typeid (m_x).name() << endl; cout

C++学习笔记(一)模板类的友元模板函数Boolan

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include<iostream> #include<string> using namespace std; template<class T> class Test; template<class T> ostream& operator<&l

c++学习笔记啊——类模板(1)

模板 模板是泛型编程的基础,能够处理在编译时不知道类型的情况 (1)模板函数 模板函数(function template) 一个模板函数就是一个公式,可以用来生成针对特定类型的函数版本,如下compare模板的例子 1 template < typename T > 2 int compare(const T&v1,const T&v2) 3 { 4 //其实只要返回一个值,后面的就不会再执行了 5 if(v1v2) return 1; 6 return 0; 7 } 函数说

C++学习之模板 (二) -----类模板

由于将函数和类模板放在一块篇幅较大,我们今天将其拆分为两篇博文. 上篇博文我们讨论了函数模板的简单应用,本篇我们继续讨论模板的另一板块--类模板. 1).作用:类模板类似于代码产生器,根据用户输入的类型不同,产生不同的class: 2).编译: a):检查模板class 的自身语法: b):根据用户指定的类型 如 vector<string>,去实例化一个模板类. 注意: 不是实例化所以的代码,而仅仅实例化用户调用的部分: 类模板:简单实现如下; 1 #include <iostream

Effective C++ Item 43 学习处理模板化基类内的名称

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:可在derived class templates 内通过 "this->" 指涉 base class templates 内的成员名称,或藉由一个明白写出的 "base class 资格修饰符"完成. 示例: class CompanyA{ public: //... void sendCleartext(const std::string &

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

类模板的目的 设计通用的类型式,以适应广泛的成员数据型式 类模板的定义格式 template<模板形式参数列表>class 类名称{...}; 原型:template<typename T> class A; 类模板的成员 像普通类的成员一样定义 定义在类中或类外均可,后者需要在类名后列些模板参数,以区别非模板类的成员函数 template<typename T> T A<T>::f(u) 类成员函数的模板 成员函数可以使用其他模板 template<

Effective C++:条款43:学习处理模板化基类内的名称

(一) 注意从 "面向对象的C++" 转向 "模板C++" 时继承可能遭遇问题 :由于基类模板可能被特化,而该特化版本可能会改变成员,因此C++拒绝在模板化基类中寻找继承而来的名称. (二) 看下面的例子: 假设将信息传送到不同的公司去,传送方式包括明文传送和密文传送,采用模板类的设计方法: class CompanyA { public: ... void sendClearText(const string& msg); void sendEncrypt

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

当一个类包含一个友元声明时,类与友元各自是否是模板是相互无关的.如果一个类模板包含一个非模板友元,则友元被授权可以访问所有模板实例.如果友元自身是模板,类可以授权给所有友元模板实例,也可以只授权给特定实例. 1. 一对一友好关系 类模板与另一个(类或函数)模板间友好关系的最常见形式是建立对应实例及其友元间的友好关系.例如,我们的 Blob 类应该讲 BlobPtr 类和一个模板版本的 Blob 相等运算符定义为友元. 为了引用(类或函数) 模板的一个特定实例,我们必须首先声明模板自身.一个模板声

c++模板类学习简单

1.模板的概念 我们已经学过重载(Overloading),对重载函数而言,C++的检查机制能通过函数参数的不同及所属类的不同.正确的调用重载函数.例如,为求两个数的最大值,我们定义MAX()函数需要对不同的数据类型分别定义不同重载(Overload)版本. //函数1. int max(int x,int y) {  return(x>y)?x:y ; } //函数2. float max( float x,float y) {  return (x>y)? x:y ; } //函数3. d