类模板(泛型编程)

什么是类模板

类似函数模板,淡化数据类型,使用通用数据类型的模板。对仅成员数据类型不同的类的抽象,比如,有两个或多个类,其功能是相同的,仅仅是数据类型的不同,那就可以声明为类模板。

一般形式:template  <typename 参数名1,typename  参数名2,...>

template<typename T>
class Test
{
    Test(T t){}
    T Get() {}
    void Set(T val) {}
private: 
    T DateMember;//类属(类型参数化)参数必须至少在类说明中出现一次
};

int main()
{
    Test<int> a(10);//类模板一定要显示调用
    a.Set(20);
    a.Get();
    system("pause");
    return 0;
}
  • 类模板用于实现类所需数据的类型参数化
  • 类模板在表示如数组、表、图等数据结构显得特别重要,这些数据结构的表示和算法不受所包含的元素类型的影响
  • 和函数模板一样都需要进行二次编译(在声明的地方对模板代码本身进行编译,在调用的地方对参数替换后在进行编译)
  • 函数模板可以自动类型推导,类模板不能自动类型推导

继承中的类模板

子类从模板类继承时,需要让编译器知道父类的数据类型具体是什么。

怎么理解上面的话:以为在类初始化对象时需要分配内存空间大小,如果不显示声明,那么这个类无法初始化(数据类型的本质:固定大小内存块的别名)

类模板派生普通类

template<typename T>
class A
{
public:
    A(T x)
    {
        t = x;
    }
    void Print()
    {
        cout << "t = " << t << endl;
    }
protected:
    T t;
};

class B:public A<int>
{
public:
    B(int a, double b) :A<int>(a)//必须显示声明
    {
        y = b;
    }
    void Print()
    {
        A<int>::Print();//必须显示声明
        cout << "y = " << y << endl;
    }
private:
    double y;
};

int main()
{
    A<int> a(3);//必须显示声明
    a.Print();

    B b(8, 2.5);
    b.Print();
    system("pause");
    return 0;
}

在定义B类时,A类已实例化成了int型的模板类(编译时完成)。

类模板派生类模板

template<typename T>
class A
{
public:
    A(T x)
    {
        t = x;
    }
    void Print()
    {
        cout << "t = " << t << endl;
    }
protected:
    T t;
};

template<typename T>
class B:public A<T>
{
public:
    B(int a, double b) :A<T>(a)//必须显示声明
    {
        y = b;
    }
    void Print()
    {
        A<T>::Print();//必须显示声明
        cout << "y = " << y << endl;
    }
private:
    T y;
};

int main()
{
    A<int> a(3);//必须显示声明
    a.Print();

    B<T> b(8, 2.5);
    b.Print();
    system("pause");
    return 0;
}

类模板的作用

是泛型编程的基础,就是用独立于任何特定类型的方式来编写代码,简单的来说,类是对象的抽象,对象时具体的,而模板是类的抽象,用模板能定义出具体的类。

C++中多态分为两种:

动态:虚函数

静态:函数重载,泛型编程

类模板中的static关键字

  • 从类模板实例化的每个模板类有自己的类模板数据成员,该模板类的所有对象共享一个static数据成员
  • 和非模板类的static数据成员一样,模板类的static数据成员也应该在文件范围定义和初始化
  • 每个模板类有自己的类模板的static数据成员副本
#pragma warning(disable : 4996)
#include <iostream>
using namespace std;
 
template <typename T>
class A
{
public:
    static T m_a;
};
 
template <typename T>
T A<T>::m_a = 0;
 
int main()
{
    A<int> a1, a2, a3;
    a1.m_a = 10;
    a2.m_a++;
    a3.m_a++;
    cout << A<int>::m_a << endl;
 
    A<char> a4, a5, a6;
    a4.m_a = 'a';
    a5.m_a++;
    a6.m_a++;
    cout << A<char>::m_a << endl;
 
    system("pause");
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章