浅析类模板

来源:互联网 发布:淘宝客佣金在哪里设置 编辑:程序博客网 时间:2024/05/29 19:29

首先还是来看一个题目:


关于函数模版和类模板,其实之前一直都在用,比如STL中的容器就是标准的类模版,各种算法就是函数模版,今天打算对这个知识点做个梳理。既然是模版(template),就是抽象出类或函数中共性的部分,用更大的容器来盛放它们。如果将之前的基本数据类型(int, float, char, bool, void...)或者自定义的数据类型比作是不同形状的杯子,这些杯子可以用来装不同种类的液体,比如茶杯、咖啡杯、牛奶杯等等,那么模版的出现就是泛化这些杯子的差异,在定义时用比较模糊的概念“杯子”来概括不同种类的杯子。


不管是函数模版还是类模板,在使用前都要经过实例化,即要么根据给定数据来推断数据的的类型(函数模板),要么就直接(显式)告诉编译器数据的类型(类模板),经过实例化后的函数和类就成了特定类型的函数和类,进而由编译器沈生成代码。反之,没有使用的函数模板和类模板是不会被实例化的,“不确定性”才会产生模板,“实例化”就是用来消除不确定性的。


最后,贴一段类模板的示例代码,除了抽象出一些参数外,和普通类的定义并无二致。

#include <iostream>#include <vector>#include <string> using namespace std;//类模板的使用 template<typename Type>class Students { private: string name; int age; vector<Type> scores;//类模板本身含有类模板成员 public: Students(string n = "zhangsan", int a = 25, vector<int> sc = {}) :name(n), age(a), scores(sc){} ~Students(){} string getName() const; int getAge() const; friend ostream& operator << <>(ostream&, const Students<Type>&);//对<<进行运算符重载,注意声明处<<后有<>,而定义处无<> }; template<typename Type>string Students<Type>::getName() const { return this->name; } template<typename Type>int Students<Type>::getAge() const { return this->age; } template<typename Type>ostream& operator << (ostream& os, const Students<Type>& out) { os << out.name << "===>" << out.age << endl; for (vector<int>::const_iterator it = out.scores.begin(); it != out.scores.end(); it++) { os << *it << endl; } return os; }int main(void){vector<int> scores = { 90, 80, 60 };Students<int> stu1("Ace", 26, scores);cout << stu1;return 0;}


输出结果:

上段代码中,类模板内含有类模板成员,对Students的初始化实际上就是对vector的初始化;此外,由于模板类的成员函数都是模板函数,因此在内外定义时需要在函数名前加上template模板关键字。最后要注意的一点是对操作符<<和>>的重载,千万不要在内内部声明的时候在运算符后忘记<>,这表明此函数为类的友元函数模板。


以上。


0 0
原创粉丝点击