STL2-类模板
1、類模板實現(xiàn)
函數(shù)模板在調(diào)用時可以自動類型推導
類模板必須顯式指定類型
?
2、類模板派生普通類
注意:
(1)class Cat :public Animal<int> ? //繼承時必須指定類型
(2)Cat(int age,int id ,int color):Animal<int>(age,id)? //構造函數(shù)也需要繼承
#include<iostream>using namespace std; template<class T> class Animal { public:T mAge;T mId;public:Animal(T age, T id){this->mAge = age;this->mId = id;}void Show(){cout << "父類" << endl;cout << "ID:" << mId << " Age:" << mAge << endl;} }; class Cat :public Animal<int> //繼承時必須指定類型 { public:int mColor; public:Cat(int age,int id ,int color):Animal<int>(age,id){mAge = age;mId = id;this->mColor = color;}void Show(){cout << "子類" << endl;cout << "ID:" << mId << " Age:" << mAge<< " mColor:"<<mColor<< endl;}};int main(void) {Animal<int> a(12,12);a.Show();Cat c(1,1,1);c.Show();return 0; }運行結果:?
3、類模板派生類模板
注意:
(1)template<class T> class B:public A<T> //繼承時不需要指定類型
(2)B(T age,T id ,T color):A<T>(age,id)? //雖然不需要具體指定類型但是構造函數(shù)也需要繼承
#include<iostream>using namespace std; template<class T> class A { public:T mAge;T mId;public:A(T age, T id){this->mAge = age;this->mId = id;}void Show(){cout << "父類" << endl;cout << "ID:" << mId << " Age:" << mAge << endl;} }; template<class T> class B :public A<T> //繼承時必須指定類型 { public:int mColor; public:B(T age,T id ,T color):A<T>(age,id){mAge = age;mId = id;this->mColor = color;}void Show(){cout << "子類" << endl;cout << "ID:" << mId << " Age:" << mAge<< " mColor:"<<mColor<< endl;}};int main(void) {A<int> a(12,12);a.Show();B<double> c(1.21,1.22,1.23);c.Show();return 0; }運行結果:
4、類模板類外實現(xiàn)
注意類模板中友緣函數(shù)的使用
#include<iostream> using namespace std;//不要濫用友緣函數(shù)//類外聲明 普通友緣函數(shù)方法二 template<class T> class Person; template<class T> void PrintPerson(Person<T>& p);template<class T> class Person { public://重載左移操作符 此方法linux可能編譯不通過template<class T>friend ostream& operator<<(ostream& os, Person<T>& p);//friend ostream& operator<<<T>(ostream& os, Person<T>& p);//普通友緣函數(shù)方法一 需要添加template<class T>/*template<class T>friend void PrintPerson(Person<T>& p);*///普通友緣函數(shù)方法二 friend void PrintPerson<T>(Person<T>& p);Person(T age, T id);void show(); private:T mAge;T mID; };template<class T> Person<T>::Person(T age, T id) {this->mID = id;this->mAge = age; } template<class T> void PrintPerson(Person<T>& p) {cout << "Age:" << p.mAge << " ID:" << p.mID << endl; } template<class T> void Person<T>::show() {cout << "Age:" << mAge << " ID:" << mID << endl; }//重載左移運算操作符 template<class T> ostream& operator<<(ostream &os, Person<T>& p) {os << "Age:" << p.mAge << " ID:" << p.mID << endl;return os; }void test01() {Person<int> p(10, 20);p.show();PrintPerson(p);cout << p; }int main(void) {test01();return 0; }5、類模板.h和.cpp分離編寫
注意:
(1)一般在寫類模板時將Person.h和Person.cpp合并一起寫。寫為Person.hpp(hpp即h和cpp的合并).否則可能會報錯
(2)當分開寫時,main.cpp 中include的是Person.cpp。因為只有這樣在編譯Person<int> p(10)時,編譯器才會找到構造函數(shù)并生成具體函數(shù)使用。當include的時Person.h時,編譯main.cpp時,在運行到Person<int> p(10)時,以為會在其他處有聲明,然而只有有Person<T>::Person(T age)的聲明,而沒有具體類型構造函數(shù)的聲明。(模板函數(shù)的二次編譯:一次聲明編譯,一次具體調(diào)用編譯)
如:
Person.h
#pragma once#include <iostream> using namespace std;//聲明是不編譯的 template<class T> class Person { public:Person(T age);void Show(); public:T mAge; };Person.cpp
#include"Person.h" //函數(shù)模板是二次編譯 //定義時一次編譯,并沒有生成具體的函數(shù) //具體調(diào)用第二次編譯 template<class T> Person<T>::Person(T age) {this->mAge = age; }template<class T> void Person<T>::Show() {cout << "Age:" << mAge << endl; }?
main.cpp
#include<iostream> //#include"Person.h" 錯誤 #include"Person.cpp"//正確, //因為Person<int> p(10)在編譯時用到Person<T>::Person(T age)生成具體的使用函數(shù) //所以在寫類模板時一般寫為Person.hpp 意味著h和cpp的合體 int main(void) {//讓鏈接器找文件//C++獨立編譯。第一次編譯時,構造函數(shù)定義在當前文件沒有找到//因為此函數(shù)有聲明,編譯器認為這個函數(shù)在其他文件中定義//讓鏈接器在鏈接時 去找這個函數(shù)的具體位置,如何實現(xiàn)//然而鏈接器在鏈接時,發(fā)現(xiàn)并沒有此函數(shù)的定義,因為次函數(shù)的編譯是函數(shù)模板的第一次編譯,找不著//報錯Person<int> p(10);p.Show();return 0; }運行結果:
6、類模板中static關鍵字的使用
#include<iostream> using namespace std;template<class T> class Person { public:static int a; }; //類外初始化 template<class T> int Person<T>::a = 0; int main(void) {Person<int> p1, p2, p3;Person<char> pb1, pb2, pb3;p1.a = 10;pb1.a = 100;cout << "p.a:" << p1.a <<" "<<p2.a << " " <<p3.a<< endl;cout << "pb.a:" << pb1.a << " " <<pb2.a << " " <<pb3.a<< endl;return 0; }?
?
總結
- 上一篇: python在材料方面的应用_pytho
- 下一篇: STL18常用算法