博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++中类模板的深入理解
阅读量:5265 次
发布时间:2019-06-14

本文共 5453 字,大约阅读时间需要 18 分钟。

1,多参数类模板:

     1,类模板可以定义任意多个不同的类型参数;

         1,代码示例:

1 template 
2 class Test3 {4 public:5 void add(T1 a, T2 a);6 };7 8 Test
t;

    2,类模板可以被特化:

 

               1,指定类模板的特定实现;

               2,部分类型参数必须显示指定;

               3,根据类型参数分开实现类模板;

       3,类模板的特化类型:

 

            1,部分特化 - 用特定规则约束类型参数;

                 1,上面的为部分特化;

            2,完全特化 - 完全显示指定类型参数;

       4,类模板的特化编程实验:

1 #include 
2 #include
3 4 using namespace std; 5 6 template 7 < typename T1, typename T2 > 8 class Test 9 {10 public:11 void add(T1 a, T2 b)12 {13 cout << "void add(T1 a, T2 b)" << endl;14 cout << a + b << endl;15 }16 };17 18 /* 关于上述第一个类模板的特殊实现,关于指针的特化实现 */19 template20 < typename T1, typename T2 >21 class Test < T1*, T2* > // 关于指针的特化实现22 {23 public:24 void add(T1* a, T2* b)25 {26 cout << "void add(T1* a, T2* b)" << endl;27 cout << *a + *b << endl;28 }29 };30 31 /* 定义上述第一个类模板的特殊实现,即当Test 类模板的两个类型参数完全相同时,使用这个实现;编译器并不认为在这里重新定义了一个新的模板,它认为这里是在定义第一个类模板的特殊实现;这里是部分特化; 32 */33 template34 < typename T >35 class Test < T, T > // Test 类模板的两个类型参数完全相同时,使用这个实现;36 {37 public:38 void add(T a, T b)39 {40 cout << "void add(T a, T b)" << endl;41 cout << a + b << endl;42 }43 44 void print() // 特化实现可以重新定义新的函数;45 {46 cout << "class Test < T, T >" << endl;47 }48 };49 50 /* 定义上述第一个类模板的特殊实现,当 T1 == void* 并且 T2 == void* 时,使用这个实现; */51 template52 < > // 没有泛指类型; 53 class Test < void*, void* > // 当 T1 == void* 并且 T2 == void* 时54 {55 public:56 void add(void* a, void* b)57 {58 cout << "void add(void* a, void* b)" << endl;59 cout << "Error to add void* param..." << endl;60 }61 };62 63 int main()64 { 65 Test
t1; // 使用第一个类模板;66 Test
t2; // 使用第三个类模板,特化实现;67 Test
t3; // 使用第四个类模板,特化实现;68 69 t1.add(1, 2.5); // void add(T1 a, T2 b) 3.5;70 71 t2.add(5, 5); // void add(T a, Tb) 10;72 t2.print(); // class Test < T, T >73 74 t3.add(NULL, NULL); // void add(void* a, void* b);Error to add void* param...;75 76 Test
t4; // 未有定义指针特化时,编译器显示 14 行:error: invalid operands of types 'int*' and 'double*' to binary 'operator+';77 // 特化指针后,打印 void add(T1* a, T2* b);78 int a = 1;79 double b = 0.1;80 81 t4.add(&a, &b); // 1.182 83 return 0;84 }

            1,类模板的特化实现表象上面好像定义了不同的类模板,但其实我们仅仅是根据需要将一个类模板分开成不同的情况来实现;

            2,编译器编译过后根据我们使用的类型参数来决定究竟是哪一种实现;

       5,类模板特化注意事项:

            1,特化只是模板的分开实现:

                 1,本质上是同一个类模板;

                 2,仅仅是将模板根据需要分开来实现;

            2,特化类模板的使用方式是统一的;

                 1,必须显示指定每一个类型参数;

          

2,类模板特化与重定义有区别吗?函数模板可以特化吗?

    1,有区别;

   

3,特化的深度分析:

    1,重定义和特化的不同:

        1,重定义:

             1,一个类模板和一个新类(或者两个类模板);

                  1,重定义本质是要么是实现了两个类模板,要么是一个类模板加上 一个新的类;

                  2,特化本质是只实现同一个类模板,特化的目的仅仅是考虑一些特殊的情况类模板应该如何工作;

              2,使用的时候需要考虑如何选择的问题;

                  1,使用的时候没有统一的方式,要选择用类模板的种类或用新的类;

        2,特化:

             1,以统一的方式使用类模板和特化类;

             2,编译器自动优先选择特化类;

                  1,能用特化就不要重定义;

    2,函数模板只支持类型参数完全特化:

        1,代码示例:

1 template < typename T>  // 函数模板定义 2 bool Equal(T a, T b) 3 { 4     return a == b; 5 } 6             7 template < >  // 函数模板完全特化 8 bool Equal
(void* a, void* b) 9 {10 return a == b;11 }

    3,特化的深入理解编程实验:

1 #include 
2 #include
3 4 using namespace std; 5 6 /* 以下是类模板的重定义实现 */ 7 template 8 < typename T1, typename T2 > 9 class Test10 {11 public:12 void add(T1 a, T2 b)13 {14 cout << "void add(T1 a, T2 b)" << endl;15 cout << a + b << endl;16 }17 };18 19 /*20 template21 < >22 class Test < void*, void* > // 当 T1 == void* 并且 T2 == void* 时23 {24 public:25 void add(void* a, void* b)26 {27 cout << "void add(void* a, void* b)" << endl;28 cout << "Error to add void* param..." << endl;29 }30 };31 */32 33 /* 类模板的重定义,重新实现上面注释的模板特化,处理指针相加 */34 class Test_Void35 {36 public:37 void add(void* a, void* b)38 {39 cout << "void add(void* a, void* b)" << endl;40 cout << "Error to add void* param..." << endl;41 }42 };43 44 45 /* 以下是函数模板的特化实验 */ 46 47 template48 < typename T >49 bool Equal(T a, T b)50 {51 cout << "bool Equal(T a, T b)" << endl;52 53 return a == b;54 }55 56 /* 函数完全特化解决浮点数比较问题 */57 template58 < >59 bool Equal
(double a, double b)60 {61 const double delta = 0.00000000000001;62 double r = a - b;63 64 cout << "bool Equal
(double a, double b)" << endl;65 66 return (-delta < r) && (r < delta);67 }68 69 /* 直接重载 */70 bool Equal(double a, double b)71 {72 const double delta = 0.00000000000001;73 double r = a - b;74 75 cout << "bool Equal(double a, double b)" << endl;76 77 return (-delta < r) && (r < delta);78 }79 80 int main()81 { 82 Test
t3; // 这里错误了,要用 Test_Void t3; 这样的 定义方式,因为重定义了类的实现方式,注销了模板特化方式;写代码时,要时刻考虑究竟是要使用类模板 还是要使用新类,这就是弊端,所以能特化时,就不要重新定义、重新实现;83 84 cout << Equal( 1, 1 ) << endl; // bool Equal(T a, T b) 185 cout << Equal<>( 0.001, 0.001 ) << endl; // 用相等符号比较两个浮点数是否相等是有问题的;用了特化后:bool Equal
(double a, double b) 186 cout << Equal( 0.001, 0.001 ) << endl; // bool Equal(double a, double b) 1;这里调用全局重载函数,因为编译器会优先寻找全局重载函数;87 88 return 0;89 }

    4,工程中的建议:

         1,当需要重载函数模板时,优先考虑使用模板特化;当模板特化无法满足需求,再使用函数重载!

      

4,小结:

    1,类模板可以定义任意多个不同的类型参数;

    2,类模板可以被部分特化和完全特化;

    3,特化的本质是模板的分开实现;

    4,函数模板只支持完全特化;

    5,工程中使用模板特化代替类(函数)重定义;

转载于:https://www.cnblogs.com/dishengAndziyu/p/10918826.html

你可能感兴趣的文章
python json.dumps 中的ensure_ascii 参数引起的中文编码问题
查看>>
Python中利用原始套接字进行网络编程的示例
查看>>
Python使用numpy实现BP神经网络
查看>>
反射常用API
查看>>
Java多线程-线程的调度(守护线程)
查看>>
NO.9章 树(遍历、BST、AVL、并查集、堆、哈夫曼)
查看>>
C#与.NET程序员面试宝典 封皮(非常重要的图)
查看>>
[转载]建立时间和保持时间
查看>>
自我介绍
查看>>
第七周
查看>>
13. (转) Android一些布局属性详解
查看>>
arm-linux-g++ 下交叉编译libxml2
查看>>
windowsXP同步Internet时间
查看>>
Typescript编译设置
查看>>
批量删除垃圾帖
查看>>
三目运算符
查看>>
js 判断当前是什么浏览器
查看>>
关于购物车添加按钮的动画(vue.js)
查看>>
JAVA环境安装配置
查看>>
js瀑布流 原理实现揭秘 javascript 原生实现
查看>>