格式:
template<class NameType,class AgeType>
緊跟著類
與函數(shù)模板區(qū)別,可以有默認(rèn)類型參數(shù)
自動(dòng)類型推導(dǎo),類模板不支持,必須顯示指定類型
成員函數(shù)一開始不會(huì)創(chuàng)建出來(lái),而是在運(yùn)行時(shí)才會(huì)創(chuàng)建
例:
template<class NameType, class AgeType>
class Person
{
public:
Person(NameType name, AgeType age)
{
this->Name = name;
this->Age = age;
}
void showPerson()
{
cout << "名字:" <<this->Name << "年齡" << this->Age << endl;
}
NameType Name;
AgeType Age;
};
void test()
{
//自動(dòng)類型推導(dǎo),類模板不支持,必須顯示指定類型
Person<string, int> p("大魔王", 1000);
p.showPerson();
};
類模板做函數(shù)參數(shù)
方式一:顯示指定類型
方式二:參數(shù)模板化
方式三:整體類型化
例:
template<class NameType, class AgeType>
class Person
{
public:
Person(NameType name, AgeType age)
{
this->Name = name;
this->Age = age;
}
void showPerson()
{
cout << "名字:" << Name << "年齡" << Age << endl;
}
NameType Name;
AgeType Age;
};
//指定傳入類型
void doWork(Person<string, int>& p)
{
p.showPerson();
};
void test()
{
//自動(dòng)類型推導(dǎo),類模板不支持,必須顯示指定類型
Person<string, int> p("大魔王", 1000);
doWork(p);
};
例2:
template<class NameType, class AgeType>
class Person
{
public:
Person(NameType name, AgeType age)
{
this->Name = name;
this->Age = age;
}
void showPerson()
{
cout << "名字:" << Name << "年齡" << Age << endl;
}
NameType Name;
AgeType Age;
};
//參數(shù)模板化
template <class T1,class T2>
void doWork(Person<T1, T2>& p)
{
p.showPerson();
};
void test()
{
//自動(dòng)類型推導(dǎo),類模板不支持,必須顯示指定類型
Person<string, int> p("大魔王", 1000);
doWork(p);
};
例3:
template<class NameType, class AgeType>
class Person
{
public:
Person(NameType name, AgeType age)
{
this->Name = name;
this->Age = age;
}
void showPerson()
{
cout << "名字:" << Name << "年齡" << Age << endl;
}
NameType Name;
AgeType Age;
};
//整體類型化
template <class T>
void doWork(T& p)
{
p.showPerson();
};
void test()
{
//自動(dòng)類型推導(dǎo),類模板不支持,必須顯示指定類型
Person<string, int> p("大魔王", 1000);
doWork(p);
};
查看數(shù)據(jù)的名稱
cout<<typeid(數(shù)據(jù)名).name()<<endl;
類模板碰到繼承
基類如果是模板類,必須讓子類告訴編譯器,基類中的T到底是什么類型,如果不告訴,那么無(wú)法分配內(nèi)存
方式一:明確類型(利用參數(shù)列表)
class Child :public base<int>
例一:
template<class T>
class base
{
public:
T m_A;
};
class Child :public base<int>
{
};
方式二:子類也是模板類
例二:
template<class T>
class base
{
public:
T m_A;
};
template <class T1,class T2>
class Child :public base<T2>
{
public:
Child(){
cout << typeid(T1).name() << endl;
cout << typeid(T2).name() << endl;
}
T1 m_B;
};
void test()
{
Child<long, double>child;
};
類模板的類外實(shí)現(xiàn)成員函數(shù)
template <class T1,class T2>
類名<T1,T2>::類名(T1 name,T2 age)
例:
template<class T1,class T2>
class base
{
public:
base(T1 name,T2 age);
void showBase();
T1 Name;
T2 Age;
};
template <class T1,class T2>
base<T1,T2>::base(T1 name,T2 age)
{
this->Name = name;
this->Age = age;
}
template<class T1,class T2>
void base<T1, T2>::showBase()
{
cout <<"姓名:" <<this->Name << endl;
cout <<"年齡:"<< this->Age << endl;
}
void test()
{
base<string,int> b("大魔王", 1000);
b.showBase();
};
類模板的分文件編寫
.h.cpp分別寫聲明和實(shí)現(xiàn)
但是由于類模板的成員函數(shù)運(yùn)行階段才去創(chuàng)建,導(dǎo)致包含.h頭文件,不會(huì)創(chuàng)建函數(shù)的實(shí)現(xiàn),無(wú)法解析外部命令
解決方案,
include .cpp文件(不建議)
類模板不要做分文件編寫,寫到一個(gè)類中即可,類內(nèi)進(jìn)行聲明和實(shí)現(xiàn),最后把后綴名改為.hpp約定俗稱
類模板碰到友元函數(shù)
友元函數(shù)類內(nèi)實(shí)現(xiàn)
friend void printPerson(Person<T1,T2>&p)
類內(nèi)實(shí)現(xiàn)例:
template<class T1,class T2>
class Person
{
friend void printPerson(Person<T1, T2>& p)
{
cout << "姓名:" << p.Name << "年齡:" << p.Age << endl;
}
public:
Person(T1 name, T2 age)
{
this->Name = name;
this->Age = age;
}
private:
T1 Name;
T2 Age;
};
void test()
{
Person<string,int> p("大魔王", 1000);
printPerson(p);
};
友元函數(shù)類外實(shí)現(xiàn)
friend void printPerson<>(Person<T1,T2>&p);//沒有<>普通函數(shù)聲明,加上<>模板函數(shù)聲明
讓編譯器看到這個(gè)函數(shù)并且看到這個(gè)Person類型
類外實(shí)現(xiàn)例:
template<class T1, class T2> class Person;
template<class T1, class T2>void printPerson(Person<T1, T2>& p);
template<class T1,class T2>
class Person
{
//友元聲明
friend void printPerson<>(Person<T1, T2>& p);
public:
Person(T1 name, T2 age)
{
this->Name = name;
this->Age = age;
}
private:
T1 Name;
T2 Age;
};
template<class T1, class T2>
//實(shí)現(xiàn)
void printPerson(Person<T1, T2>& p)
{
cout << "姓名:" << p.Name << "年齡:" << p.Age << endl;
};
void test()
{
Person<string,int> p("大魔王", 1000);
printPerson(p);
};