一、类模板与继承
当类模板碰到继承时,需要注意一下几点:
1.当子类继承的父类是一个类模板时,子类在声明的时候,要指定出父类中T的类型
2.如果不指定,编译器无法给子类分配内存
3.如果想灵活指定出父类中T的类型,子类也需变为类模板
#include<iostream>
using namespace std;
//类模板与继承
template<class T>
class Base
{
T m;
};
//class Son :public Base //错误,必须要直到父类中的T类型(分配内存),才能继承给子类
class Son :public Base<int>//必须指定一个类型
{
};
void test01()
{
Son s1;
}
//如果想灵活指定父类中T类型,子类也需要变类模板
template<class T1,class T2>
class Son2 :public Base<T2>
{
public:
Son2()
{
cout << "T1的类型为: " << typeid(T1).name() << endl;
cout << "T2的类型为: " << typeid(T2).name() << endl;
}
T1 obj;
};
void test02()
{
Son2<int, char>s2;
}
int main()
{
test01();
test02();
return 0;
}
二、 类模板成员函数类外实现
#include<iostream>
using namespace std;
#include<string>
//类模板成员函数类外实现
template<class T1, class T2>
class Person
{
public:
Person(T1 name, T2 age);//类内声明
//{
// this->m_Name = name;
// this->m_Age = age;
//}
void showPerson();//类内声明
//{
// cout << "姓名: " << this->m_Name << " 年龄: " << this->m_Age << endl;
//}
T1 m_Name;
T2 m_Age;
};
//构造函数 类外实现
template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age)
{
this->m_Name = name;
this->m_Age = age;
}
//成员函数 类外实现
template<class T1, class T2>
void Person<T1, T2>::showPerson()
{
cout << "姓名: " << this->m_Name << " 年龄: " << this->m_Age << endl;
}
void test()
{
Person<string, int>P("Tom", 20);
P.showPerson();
}
int main()
{
test();
return 0;
}
总结:类模板中成员函数类外实现时,需要加上模板参数列表
三、类模板全局函数的类内类外实现
全局函数类内实现 - 直接在类内声明友元即可
全局函数类外实现 - 需要提前让编译器知道全局函数的存在
#include<iostream>
using namespace std;
#include<string>
//通过全局函数来打印 Person 信息
//提前让编译器知道 Person 类的存在
template<class T1, class T2>
class Person;
//类外实现 函数模板的实现
template<class T1, class T2>
void printPerson2(Person<T1, T2>p)
{
cout << "类外实现---姓名: " << p.m_Name << " 年龄: " << p.m_Age << endl;
}
template<class T1,class T2>
class Person
{
//全局函数 类内实现
friend void printPerson1(Person<T1, T2>p)
{
cout << "姓名: " << p.m_Name << " 年龄: " << p.m_Age << endl;
}
//全局函数 类外实现(类内声明,类外实现)
//加空模板参数列表--->函数模板的声明
//如果全局函数是类外实现,需要让编译器提前知道这个函数的存在
friend void printPerson2<>(Person<T1, T2>p);无尖括号则为普通函数的声明
public:
Person(T1 name, T2 age)
{
this->m_Name = name;
this->m_Age = age;
}
private:
T1 m_Name;
T2 m_Age;
};
//1.全局函数在类内实现
void test01()
{
Person<string, int>p("Tom", 18);
printPerson1(p);
}
//2.全局函数在类外实现
void test02()
{
Person<string, int>p("Jerry", 18);
printPerson2(p);
}
int main()
{
//test01();
test02();
return 0;
}
总结:建议全局函数做类内实现,用法简单,而且编译器可以直接识别