一、类模板写法

1. 声明和定义写在一起

template<class T>
class Person{
public:
    Person(T age){
        this->m_age = age;
    }
    void Show(){
        cout << this->m_age << endl;
    }
    
private:
    T m_age;
};

int main()
{
    Person<int> p(20);
    p.Show();
    cout << p << endl;
    printP(p);
    
    return 0;
}

2. 声明和定义分开写,但在同一文件中

template<class T>
class Person{
public:
    Person(T age);
    void Show();
private:
    T m_age;
};

template<class T>
Person<T>::Person(T age){
    this->m_age = age;
}
template<class T>
void Person<T>::Show(){
    cout << this->m_age << endl;
}
int main()
{
    Person<int> p(20);
    p.Show();

    return 0;
}

二、类模板派生

  1. 类模板派生普通类;
  2. 类模板派生类模板;
template<class T>
class Base{
public:
    Base(T a){
        this->m_a = a;
    }
    void show(){
        cout << m_a << endl;
    }
private:
    T m_a;
};
class Derive1 : public Base<int>{
public:
    Derive1(int a):Base<int>(a){
        
    }
};
template<class T1, class T2>
class Derive2 : public Base<T1>{
public:
    Derive2(T1 a, T2 b):Base<T1>(a){
        this->b = b;
    }
    void show(){
        Base<T1>::show();
        cout << b << endl;
    }
private:
    T2 b;
};
int main()
{
    Derive1 d(10);
    d.show();
    cout << "---------" << endl;
    Derive2<int, char> dd(100, 'a');
    dd.show();
    return 0;
}

输出:

10
---------
100
a

三、类模板中写友元函数

1. 声明和定义一起写

template<class T>
class Person{
    // 友元重载
    friend ostream& operator<<(ostream &os, Person<T> &p){
        os << p.m_age;
        return os;
    }
    // 普通友元
    friend void printP(Person<T> p){
        cout << p.m_age << endl;
    }
public:
    Person(T age){
        this->m_age = age;
    }
    void Show(){
        cout << this->m_age << endl;
    }
    
private:
    T m_age;
};

int main()
{
    Person<int> p(20);
    p.Show();
    cout << p << endl;
    printP(p);
    
    return 0;
}

2. 声明和定义分开写

// 前置声明
template<class T> class Person;
template<class T> ostream& operator<<(ostream &os, Person<T> &p);
template<class T> void printP(Person<T> p);

template<class T>
class Person{
    // 友元重载
    friend ostream& operator<< <T>(ostream &os, Person<T> &p);
    // 普通友元
    friend void printP<T>(Person<T> p);
public:
    Person(T age);
    void Show();
    
private:
    T m_age;
};

template<class T>
Person<T>::Person(T age){
    this->m_age = age;
}

template<class T>
void Person<T>::Show(){
    cout << this->m_age << endl;
}

template<class T>
ostream& operator<<(ostream &os, Person<T> &p){
    os << p.m_age << endl;
    return os;
}

template<class T>
void printP(Person<T> p){
    cout << p.m_age << endl;
}

int main()
{
    Person<int> p(20);
    p.Show();
    cout << p << endl;
    printP(p);
    
    return 0;
}

四、结论

  1. 类模板中不要滥用友元;
  2. 将类模板的声明和定义放在同一个文件中,一般为 .hpp 文件;

五、类模板中的 static 变量

每个具体的类都有属于自己的静态变量,每个具体类的实例对象共享自己具体类的静态变量

template<class T> int Person<T>::s_a = 0;
int main()
{
    Person<int> p1(10), p2(20);
    Person<char> pp1(10), pp2(20);
    p1.s_a = 1;
    pp1.s_a = 100;
    cout << p2.s_a << endl;
    cout << pp2.s_a << endl;
    
    return 0;
}

输出:

1
100