C++面向对象高级编程(八)模板
技术在于交流、沟通,转载请注明出处并保持作品的完整性。
这节课主要讲模板的使用,之前我们谈到过函数模板与类模板 (C++面向对象高级编程(四)基础篇)这里不再说明
1.成员模板
成员模板:参数为template,以下面的代码为例,T1和T2 确定下来后, 后面的U1和U2 仍然可以变化,其实可以直接理解成形参类型不确定
template <class T1, class T2> class pair_test { public: typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; pair_test(): first(T1()),second(T2()) { cout<<"类模板"<<endl; } pair_test(const T1& a, const T2& b):first(a),second(b) {} template <class U1, class U2> //成员模板 pair_test(const pair_test<U1, U2>& p): first(p.first),second(p.second) { cout<<"成员模板"<<endl; } template <class X1, class X2>//帮助理解 void test_test(const X1 a, const X2 b) { cout<< a << b <<endl; } };
定义两个测试类
class Base1{}; class Drived1:public Base1{}; class Base2{}; class Drived2:public Base2{};
调用端
int main() { pair_test<Drived1, Drived2> p; pair_test<Base1, Base2> p2(p);//把子类12构成的pair 放进基类12构成的pair中 做参数可以 反之不可以 : 父类指针可以指向子类对象,子类指针不可指向父类对象 int a = 1; int b = 2; p.test_test(a,b); return 0; }
输出结果
2.模板特化
模板特化:为了满足一些特定的需求,需要对模板进行特化,也就是特殊处理.
先说一下模板泛化,以下面代码为例,只要你指定Key的类型,就可以模板化
template <class Key> class hash_test {}; //泛化
模板特化就是指定Key的类型做模板化,
template <class Key> class hash_test { public: hash_test() { cout<<"模板泛化"<<endl; } }; //泛化 template <> class hash_test<char> { //特化 public: size_t operator()(char x) const { cout<< "模板特化char" <<endl; return x; } };
调用端
int main() { hash_test<int> a; char c = 'c'; hash_test<char> b; cout<<b(c)<<endl; return 0; }
输出结果
3.偏特化
偏特化:模板的偏特化是指需要根据模板的某些但不是全部的参数进行特化.偏特化非为两种,一种是个数上偏,一种是范围上偏.如果你的类模板是针对bool型变量,bool变量的存储只需要一个二进制数,使用一个字节都是在浪费存储空间
a.个数上的偏特化
template <typename T, typename Type> class vector_test1 { public: vector_test1() { cout<<"没有偏特化"<<endl; } }; //可以转化成 template<typename Type> class vector_test1<bool, Type> { public: vector_test1() { cout<<"个数上的偏特化"<<endl; } };
调用端
int main() { vector_test1<int,int> a; vector_test1<bool,int> b;//指定第一个参数 }
输出结果
b.范围偏特化
指定要特化参数的范围,接受一个对象,和接受一个指针为例
template <typename T> class C { public: C() { cout<<"接收对象"<<endl; } }; template <typename T> class C<T*> //只接受指针变量 { public: C() { cout<<"接收指针"<<endl; } };
调用端
int main() { C<int> c; C<int*> c1; return 0; }
输出结果
4 模板 模板参数
模板 模板参数:参数中有一个是模板
template <typename T,template <typename C> class Container> class XCls { private: Container<T> c; public: }; template<typename T> using Lst = list<T, allocator<T>>;
调用端
int main() { // XCls<string, list> mylst1;//编译过不了 容器需要好几个模板参数 XCls<string, Lst> mylst2;//你需要这样用 这个时候 XCLs中的 成员变量c == list<string> return 0; }
参照<<侯捷 C++面向对象高级编程>>