ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

类模板(下)

类模板(下) 文章目录类模板的局部特化类模板可以定义多个类型参数类模板可以被局部特化思考为什么需要特化而不重新定义新类非类型模板参数函数模板的模板参数可以是普通数值代码实例 非类型模板参数与特化工程问题内存越界的问题常发生于数组的使用中内存泄漏和内存多次释放常发生于指针的使用过程中智能指针代码实例 智能指针的创建与使用小结类模板的局部特化类模板可以定义多个类型参数#include cstdlib #include iostream using namespace std; templatetypename T1, typename T2 class Test { public: void test(T1 t1, T2 t2){ cout t1t2 endl; } }; int main() { Testdouble, int t; t.test(10.001, 5); return 0; }类模板可以被局部特化可以指定类模板的特定实现并要求某些类型参数仍然必须得模板的用户指定#include cstdlib #include iostream using namespace std; templatetypename T1, typename T2 class Test { public: void add(T1 a, T2 b) { cout(a b)endl; } }; /* templatetypename T class TestT, T { public: void add(T a, T b) { coutadd(T a, T b)endl; coutstatic_castT(a b)endl; } }; */ templatetypename T class TestT, int { public: void add(T a, int b) { coutadd(T a, int b)endl; couta bendl; } }; templatetypename T1, typename T2 class TestT1*, T2* { public: void add(T1* a, T2* b) { coutadd(T1* a, T2* b)endl; //两个指针相加是没有意义的这也就是为什么要特化的原因 } }; int main(int argc, char *argv[]) { int i 0; int j 0; Testdouble, int t; // T, int Testlong, long ti; // T1, T2 Testfloat, int tt; // T, int Testint*, int* tp; // T*, T* t.add(10.0001, 8); ti.add(2, 3); tt.add(4, 5); tp.add(i, j); cout Press the enter key to continue ...; cin.get(); return EXIT_SUCCESS; }思考为什么需要特化而不重新定义新类特化和重新定义新类看上去没有本质区别但是如果定义新类那么将变成一个类模板和一个新类使用的时候需要考虑究竟是用类模板还是用新类而特化可以统一的方式使用类模板和特化类编译器自动优先选择特化类注意一下主模版完全特化局部特化这3者的语法区别非类型模板参数函数模板和类模板的模板参数可以是普通数值函数模板的模板参数可以是普通数值#include cstdlib #include iostream using namespace std; templatetypename T, int N void func() { T array[N] {0}; for(int i 0; i N; i) { array[i] i 1; coutarray[i] ; } coutendl; } int main(int argc, char *argv[]) { funcint, 5(); funcfloat, 10(); cout Press the enter key to continue ...; cin.get(); return EXIT_SUCCESS; }一道面试题怎么求 前N项和 最快代码实例 非类型模板参数与特化#include cstdlib #include iostream using namespace std; templateint N class Sum { public: static const int VALUE SumN - 1::VALUE N; //小知识点VALUE被放入符号表 static修饰在全局数据区 不会给VALUE分配空间 //递归的思想 //编译器 编译的时候 计算 }; //特化类 template class Sum1 //递归的出口 { public: static const int VALUE 1; }; int main(int argc, char *argv[]) { coutSum10::VALUEendl; //编译器二次编译 coutSum100::VALUEendl; cout Press the enter key to continue ...; cin.get(); return EXIT_SUCCESS; }非类型模板参数的限制​ 变量不能作为模板参数intn10;coutSumn::VALUEendl;//error​ 浮点数和类对象不能作为模板参数coutSum10.001::VALUEendl;//error​ 全局指针不能作为模板参数tips:编译器的推导过程是在编译阶段完成的。因此 编译器的推导必须依赖于特化类否则推导过程 无法结束。(递归)工程问题在实际工程中内存操作是bug的重要来源C将堆内存交由程序员自由使用因此​ 未及时释放将产生内存泄漏​ 重复释放同一段内存行为未知​ 使用越界操作了不属于自己的内存思考怎样最大限度的避开上述的使用问题内存越界的问题常发生于数组的使用中解决方案数组类工程中在非特殊情况下要求开发者使用预先编写的数组类对象代替C语言中的原生数组内存泄漏和内存多次释放常发生于指针的使用过程中解决方案智能指针工程中要求开发者使用预先编写的智能指针类对象代替C语言中的原生指针什么是智能指针智能指针工程中的智能指针是一个类模板​ 通过构造函数接管申请的堆内存​ 通过析构函数确保堆内存被及时释放​ 通过重载指针运算符 * 和 - 模拟指针的行为​ 通过重载比较运算符 – 和 ! 模拟指针的比较代码实例 智能指针的创建与使用SmartPointer.h#ifndef _SMARTPOINTER_H_ #define _SMARTPOINTER_H_ templatetypename T class SmartPointer { protected: T* m_pointer; public: SmartPointer(); SmartPointer(const T* pointer); ~SmartPointer(); T* operator-(); T operator*(); }; #endifSmartPointer.hpp#ifndef _SMARTPOINTER_DEF_H_ #define _SMARTPOINTER_DEF_H_ #include SmartPointer.h templatetypename T SmartPointerT::SmartPointer() //无参构造函数初始化为NULL { m_pointer NULL; } templatetypename T SmartPointerT::SmartPointer(const T* pointer) //通过构造函数接管申请的堆内存 { m_pointer const_castT*(pointer); } templatetypename T SmartPointerT::~SmartPointer() //通过析构函数确保堆内存被及时释放 { delete m_pointer; } templatetypename T T* SmartPointerT::operator-() //重载 * 运算符 { return m_pointer; } templatetypename T T SmartPointerT::operator*() //重载 - 运算符 { return *m_pointer; } #endifmain.cpp#include cstdlib #include iostream #include SmartPointer.hpp using namespace std; class Test //测试-类 { public: int i; void print() { coutiendl; } }; int main(int argc, char *argv[]) { SmartPointerint pi new int(5); // //SmartPointerint pi(new int(5) ); SmartPointerTest pt new Test(); cout*piendl; //*sp sp.operator* () *pi 100; cout*piendl; pt-i 20; //pt- pt.operator- () pt-print(); cout Press the enter key to continue ...; cin.get(); return EXIT_SUCCESS; }小结类模板中可以有一个或多个未指定的泛指类型​ 可以在需要的特化类模板​ 特化可以统一的方式使用类模板和新定义的类​ 特化类总是被编译器优先选择使用​ 模板的参数可以是普通数值​ 数组类和智能指针可以最大限度的避免内存相关的bug
返回列表