C++ 模板(泛型)

模板概念:模板是建立通用模具,大大提高复用性,类型参数化

C++泛式编程思想,主要利用的技术就是模板

C++提供模板机制:函数模板类模板

函数模板类模板区别: 

       ① 类模板没有自动类型推导使用方式

       ② 类模板在模板参数列表中可以有默认参数


一、函数模板

        作用:建立通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型代表。

        语法template<typename T>

                 [template  ——声明创建模板]

                 [typename  ——表面其后面的符号是一种数据类型,可以用class替代]

                 [T   ——通用的数据类型,名称可以替换,通常用大写字母]

                 使用方式:自动类型推导显示指定类型

                注:① 自动类型推导,必须推导出一致的类型类型T,才能使用

                        ② 模板必须要确定出T的数据类型,才可以使用


//函数模板  
template<typename T>    //声明模板,T是一个通用数据类型
void swapTest(T& a, T &b)
{
    T temp = a;
    a = b;
    b = temp;
}

//排序模板 (从小到大)
template<typename T>
void sortTest(T arr[],int len)
{
    for(int i=0;i<len;i++)
    {
        int min = i; //最小值下标
        for(int j=i+1;j<len;j++)
        {
            //认定最小值 比 遍历的数值小
            if(arr[min] > arrp[j])
                min = j;
        }

        //交换min 和 i元素
        if(min != i)    
           swapTest<T>(arr[min],arr[i]);
    }
}


int main()
{
    int nA = 10; int nB = 20;
    float fA = 10.0; float fB = 20.0;
    //模板使用方式
    swapTest(nA ,nB);         //1.自动类型推导
    swapTest<float>(fA ,fB);  //2.显示指定类型

    //排序案例:
    char charArr[] = "bacfed";
    sortTest<char>(charArr,sizeof(charArr)/sizeof(char));

    int intArr[] = {3,4,2,6,1,,7,5,9,8};
    sortTest<int>(intArr,sizeof(intArr)/sizeof(int));

    system("pause");
    return 0;
}

        普通函数与函数模板区别:

              ① 普通函数调用可以发生隐式类型转换

              ② 函数模板 用自动类型推导,不可发生隐式类型转换

              ③ 函数模板 用显示指定类型,可以发生隐式类型转换

       调用规则:

              ① 如果函数模板和普通模板都可以调用,优先普通函数

              ② 可以同空模板参数列表,强制调用函数模板

              ③ 函数模板可以发生函数重载

              ④ 如果函数模板可以产生更好匹配优先函数模板

二、类模板

        作用:建立通用类,类中成员 数据类型可以不具体制定,用虚拟的类型代表。

        语法:template<class T>

                 [template  ——声明创建模板]

                 [class  ——表面其后面的符号是一种数据类型,可以用typename替代]

                 [T   ——通用的数据类型,名称可以替换,通常用大写字母]

                 使用方式:自动类型推导,显示指定类型

         创建时机:类模板中成员函数在调用时创建

         类模板对象做函数参数:① 指定传入类型  ② 参数模板化  ③ 整个类模板化

//类模板
template<class T1,class T2= int> //默认参数类型
class Person
{
public:
    Person(T1 name,T2 age):m_name(name),m_age(age){}


    NameType m_name;
    AgeType m_age;
}

//1.指定传入类型
void print1(const Person<string,int> &p){}

//2.参数模板化
template<typename T1,typename T2>
void print2(const Person<T1,T2> &p){};

//3.整个类模板化
template<typename T>
void print3(const T &p){};

int main()
{
    //使用方法
    Person<string,int> p1("Test",18);   //指定类型
    Person<string> p2("Test2",18);      //默认参数类型

    //指定传入类型 (print1())
    print1(Person<string,int>("TEST",18));    
           
    //参数模板化 (print2<string,int>())
    print2(Person<string,int>("TEST",18));   

    //整个类模板化 (print3<Person<string,int>>())
    print3(Person<string,int>("TEST",18));


    system("pause");
    return 0;
}

  类模板继承

  注意事项:

          当子类继承的父类时一个模板时,子类在声明时,要指出父类中T的类型

          如果不指定,编译器无法给予子类分配内存

          如果要灵活指定父类中T的类型,子类也需要变为模板

template<class T>
class Base
{
    T m;
}

//class Son : public Base<int>   //必须指定一个类型

//灵活指定父类中T类型,子类也需要是模板
template<class T1,class T2>      //T1:父类T类型  ,T2:子类T2类型
class Son : public Base<T1>
{
    T2 obj;
}

int main()
{
    Son<int,char> s1; //int--父T,char--子T2

    system("pause");
    return 0;
}

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页