zoukankan      html  css  js  c++  java
  • 第五十九课、类模板的深度剖析

    一、多参数的类模板

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

    2、类模板可以被特化

    (1)、指定类模板的特定实现

    (2)、部分类型参数必须显示指定(如class Test<T, T> 就是现实指定T)

    (3)、根据类型参数分开实现类模板(同一个模板根据需要用不同方式来实现而已)

    (4)、类模板的特化类型

    A、部分特化:用特定规则约定类型参数(仍然存在类型参数

    B、完全特化:完全显示指定类型参数

    (5)、特化注意事项

    A、特化只是模板的分开实现(实现的功能都一样,本质上还是同一个模板,根据需要使用不同的实现方式而已)
    B、特化类模板的使用方式是统一的(定义对象时必须显示指定每一个参数的类型

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    template
    < typename T1, typename T2 >
    class Test
    {
    public:
        void add(T1 a, T2 b)
        {
            cout << "void add(T1 a, T2 b)" << endl;
            cout << a + b << endl;
        }
    };
    
    template
    < typename T1, typename T2 >  //部分特化,因为还有类型参数
    class Test < T1*, T2* >      // 关于指针的特化实现,特化时在这里显示指定参数的类型,如这里的< T1*, T2*>
    {               // 用以实现上述模板的特殊情况,本质上还是同一个模板 public: void add(T1* a, T2* b) { cout << "void add(T1* a, T2* b)" << endl; cout << *a + *b << endl; } }; template < typename T >//部分特化 class Test < T, T > // 当 Test 类模板的两个类型参数完全相同时,使用这个实现 { public: void add(T a, T b) { cout << "void add(T a, T b)" << endl; cout << a + b << endl; } void print()//特化类可以有自己的成员函数 { cout << "class Test < T, T >" << endl; } }; template < >//完全特化 class Test < void*, void* > // 当 T1 == void* 并且 T2 == void* 时 { public: void add(void* a, void* b) { cout << "void add(void* a, void* b)" << endl; cout << "Error to add void* param..." << endl; } }; int main() { Test<int, float> t1; Test<long, long> t2;//选择参数相同的特化类模板 Test<void*, void*> t3;//选择void*时的特化类模板(优先于两个参数相同的那个) t1.add(1, 2.5); t2.add(5, 5); t2.print(); t3.add(NULL, NULL); Test<int*, double*> t4;//选择指针时的版本 int a = 1; double b = 0.1; t4.add(&a, &b); return 0; } //输出结果 /* void add(T1 a, T2 b) 3.5 void add(T a, T b) 10 class Test < T, T > void add(void* a, void* b) Error to add void* param... void add(T1* a, T2* b) 1.1 */

    二、特化与重定义的区别

    1、重定义

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

    (2)、使用的时候需要考虑如何选择的问题

    2、特化

    (1)、以统一的方式使用类模板和特化类(定义对象是显示指定参数

    (2)、编译器自动优先选择特化类

    (3)、函数模板的特化(只能完全特化)

    3、工程中的建议

    (1)、当需要重载函数模板时,优先考虑使用模板特化

    (2)、当特化无法满足需求时,再考虑函数模板

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    template
    < typename T1, typename T2 >
    class Test
    {
    public:
        void add(T1 a, T2 b)
        {
            cout << "void add(T1 a, T2 b)" << endl;
            cout << a + b << endl;
        }
    };
    
    template
    < typename T1, typename T2 >
    class Test < T1*, T2* >      // 关于指针的特化实现
    {
    public:
        void add(T1* a, T2* b)
        {
            cout << "void add(T1* a, T2* b)" << endl;
            cout << *a + *b << endl;
        }
    };
    
    template
    < typename T >
    class Test < T, T >    // 当 Test 类模板的两个类型参数完全相同时,使用这个实现
    {
    public:
        void add(T a, T b)
        {
            cout << "void add(T a, T b)" << endl;
            cout << a + b << endl;
        }
        void print()
        {
            cout << "class Test < T, T >" << endl;
        }
    };
    /*
    template
    <  >
    class Test < void*, void* >    // 当 T1 == void* 并且 T2 == void* 时
    {
    public:
        void add(void* a, void* b)
        {
            cout << "void add(void* a, void* b)" << endl;
            cout << "Error to add void* param..." << endl;
        }
    };
    */

    //类模板的重定义,本质上已经是一个新的类 class Test_void { public: void add(void* a, void* b) { cout << "void add(void* a, void* b)" << endl; cout << "Error to add void* param..." << endl; } };
    /************************ 函数 *******************************/ template
    < typename T> bool Equal(T a, T b) { cout << "bool Equal(T a, T b)" << endl; return a == b; } //函数特化 template < >//只能完全特化 bool Equal(double a, double b) { cout << "bool Equal(double a, T double)" << endl; const double delta = 0.00000000000001; double r = a - b; return (-delta < r) && (r < delta); } //函数重定义 bool Equal(double a, double b) { const double delta = 0.00000000000001; double r = a - b; return (-delta < r) && (r < delta); } int main() { //Test<void*, void*> t3; Test_void t3; t3.add(NULL, NULL); cout << endl; cout << Equal<>(1.2, 0.6) << endl;//< > 限定编译器只匹配模板 return 0; }

    四、小结

    (1)、类模板可以定义任意多个类型不同的参数

    (2)、类模板可以被部分特化完全特化

    (3)、特化的本质模板的分开实现

    (4)、函数模板只支持完全特化

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

  • 相关阅读:
    VC得到当前目录与得到应用程序目录的一个应用
    VC回车键的使用
    VC保存和显示数据库图像(BMP)
    windows2003 oracle817过防火墙方法
    美化VC界面(用户登录界面)
    系统要关闭,可我程序还有事要处理?
    VC保存和显示数据库图像(JPG、JPEG)
    VC应用程序快捷方式带参数
    O(n)回文子串算法
    [转]经典字符串哈希算法
  • 原文地址:https://www.cnblogs.com/gui-lin/p/6376527.html
Copyright © 2011-2022 走看看