類模板
類模板語法
類模板作用:
建立一個通用類,類中的成員 數(shù)據(jù)類型可以不具體定制,用一個虛擬的類型來代表。
語法:
template<typename T>
類
解釋:
template … 聲明創(chuàng)建模板
typename … 表面其后面的符號是一種數(shù)據(jù)類型,可以用class代替
T … 通用的數(shù)據(jù)類型,名稱可以替換,通常為大寫字母
#include <iostream>
using namespace std;
#include <string>
template<class NameType,class AgeType>
struct Person
{
public:
Person(NameType name, AgeType age)
{
this->m_Name = name;
this->m_Age = age;
}
void showPerson()
{
cout << "name:" << this->m_Name << "age:" << this->m_Age << endl;
}
NameType m_Name;
AgeType m_Age;
};
void test01()
{
Person<string, int>p1("孫悟空", 999);
p1.showPerson();
}
int main()
{
test01();
return 0;
}
總結(jié):類模板和函數(shù)模板語法相似,在聲明模板template后面加類,此類稱為模板
類模板與函數(shù)模板區(qū)別
類模板與函數(shù)模板區(qū)別主要有兩點:
1、類模板沒有自動類型推導(dǎo)的使用方式
2、類模板在模板參數(shù)列表中可以有默認(rèn)參數(shù)
#include <iostream>
using namespace std;
#include <string>
template<class NameType, class AgeType = int>
struct Person
{
public:
Person(NameType name, AgeType age)
{
this->m_Name = name;
this->m_Age = age;
}
void showPerson()
{
cout << "name:" << this->m_Name << "age:" << this->m_Age << endl;
}
NameType m_Name;
AgeType m_Age;
};
//1、類模板沒有自動類型推導(dǎo)的使用方式
void test01()
{
//Person p1("孫悟空", 999);//報錯,無法用自動類型推導(dǎo)
Person<string, int>p1("孫悟空", 999);
p1.showPerson();
}
//2、類模板在模板參數(shù)列表中可以有默認(rèn)參數(shù)
void test02()
{
Person<string>p2("豬八戒",999);
p2.showPerson();
}
int main()
{
test01();
test02();
return 0;
}
總結(jié):
1、類模板使用只能用顯示指定類型方式
2、類模板中的模板參數(shù)列表可以有默認(rèn)參數(shù)
類模板中成員函數(shù)的創(chuàng)建時機(jī)
類模板中成員函數(shù)和普通類中成員函數(shù)創(chuàng)建時機(jī)是有區(qū)別的:
1、普通類中的成員函數(shù)一開始就可以創(chuàng)建
2、類模板中的成員函數(shù)在調(diào)用時才創(chuàng)建
#include <iostream>
using namespace std;
class Person1
{
public:
void showPersong1()
{
cout << "Person1 show" << endl;
}
};
class Person2
{
public:
void showPersong2()
{
cout << "Person2 show" << endl;
}
};
template<class T>
class Myclass
{
public:
T obj;
//類模板中的成員函數(shù)
void func1()
{
obj.showPerson1();
}
void func2()
{
obj.showPerson2();
}
};
int main()
{
return 0;
}
上述代碼可以運行,因為沒有調(diào)用成員函數(shù)。
#include <iostream>
using namespace std;
class Person1
{
public:
void showPerson1()
{
cout << "Person1 show" << endl;
}
};
class Person2
{
public:
void showPerson2()
{
cout << "Person2 show" << endl;
}
};
template<class T>
class Myclass
{
public:
T obj;
//類模板中的成員函數(shù)
void func1()
{
obj.showPerson1();
}
void func2()
{
obj.showPerson2();
}
};
void test01()
{
Myclass<Person1>m;
m.func1();
//m.func2();//報錯
}
int main()
{
test01();
return 0;
}
總結(jié):
類模板中的成員函數(shù)并不是一開始就創(chuàng)建的,在調(diào)用時才去創(chuàng)建
類模板對象做函數(shù)參數(shù)
學(xué)習(xí)目的:
類模板實例化出的對象,向函數(shù)傳參的方式
一共有三種傳入方式:
1、指定傳入的類型 —— 直接顯示對象的數(shù)據(jù)類型
2、參數(shù)模板化 —— 將對象中的參數(shù)變?yōu)槟0暹M(jìn)行傳遞
3、整個類模板化 —— 將這個對象類型模板化進(jìn)行傳遞
#include <iostream>
using namespace std;
#include <string>
//類模板對象做函數(shù)參數(shù)
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;
};
//1、指定傳入的類型 —— 直接顯示對象的數(shù)據(jù)類型(最常用)
void printPerson1(Person<string, int>&p)
{
p.showPerson();
}
void test01()
{
Person<string, int>p("張三", 33);
printPerson1(p);
}
//2、參數(shù)模板化 —— 將對象中的參數(shù)變?yōu)槟0暹M(jìn)行傳遞
template<class T1, class T2>
void printPerson2(Person<T1, T2>&p)
{
p.showPerson();
cout << "T1的類型為:" << typeid(T1).name() << endl;
cout << "T2的類型為:" << typeid(T2).name() << endl;
}
void test02()
{
Person<string, int>p("李四", 32);
printPerson2(p);
}
//3、整個類模板化 —— 將這個對象類型模板化進(jìn)行傳遞
template<class T>
void printPerson3(T &p)
{
p.showPerson();
cout << "T的數(shù)據(jù)類型為:" << typeid(T).name() << endl;
}
void test03()
{
Person<string, int>p("王五", 35);
printPerson3(p);
}
int main()
{
test01();
test02();
test03();
return 0;
}
總結(jié):
1、通過類模板創(chuàng)建的對象,可以有三種方式向函數(shù)中進(jìn)行傳參
2、使用比較廣泛的是第一種:指定傳入的類型
類模板與繼承
當(dāng)類模板碰到繼承時,需要注意以下幾點:
1、當(dāng)子類繼承的父類是一個類模板時,子類在聲明的時候,要指定出父類中T的類型
2、如果不指定,編譯器無法給子類分配內(nèi)存
3、如果想靈活指定出父類中T的類型,子類也需變?yōu)轭惸0?/p>
#include <iostream>
using namespace std;
template<class T>
class Base
{
T m;
};
//class Son :public Base//錯誤,必須要知道父類中T的類型,才能繼承給子類
class Son :public Base<int>
{
};
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 test01()
{
Son s1;
}
void test02()
{
Son2<int, char>S2;
}
int main()
{
//test01();
test02();
return 0;
}
總結(jié):如果父類是類模板,子類需要指出父類父類中T的數(shù)據(jù)類型
類模板成員函數(shù)類外實現(xiàn)
學(xué)習(xí)目標(biāo):能夠掌握類模板中的成員函數(shù)類外實現(xiàn)
#include <iostream>
using namespace std;
#include <string>
template<class T1,class T2>
class Person
{
public:
Person(T1 name, T2 age);
void showPerson();
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 test01()
{
Person<string, int>P("Tom", 20);
P.showPerson();
}
int main()
{
test01();
return 0;
}
總結(jié):類模板中成員函數(shù)類外實現(xiàn)時,需要加上模板參數(shù)列表
類模板分文件編寫
學(xué)習(xí)目標(biāo):
掌握類模板成員函數(shù)分文件編寫產(chǎn)生的問題以及解決方式
問題:
類模板中成員函數(shù)創(chuàng)建時機(jī)是在調(diào)用階段,導(dǎo)致分文件編寫時鏈接不到
解決:
1、解決方式1:直接包含.cpp源文件
2、解決方式2:將聲明和實現(xiàn)寫到同一個文件中,并更改后綴名為.hpp,hpp是約定的名稱,并不是強(qiáng)制
hpp
#pragma once
#include <iostream>
using namespace std;
#include <string>
//類模板分文件編寫問題以及解決
template<class T1, class T2>
class Person
{
public:
Person(T1 name, T2 age);
void showPerson();
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;
}
main
//第一種解決方式,直接包含源文件
//#include "person.cpp"http://少用
//第二種解決方式,將h和cpp中的內(nèi)容寫到儀器,將后綴改為.hpp文件
#include "person.hpp"
void test01()
{
Person <string, int>p("Jerry", 18);
p.showPerson();
}
int main()
{
test01();
return 0;
}
總結(jié):主流的解決方式是第二種,將類模板成員函數(shù)寫到一起,并將后綴名改為.hpp
類模板與友元
學(xué)習(xí)目標(biāo):掌握類模板配合友元函數(shù)的類內(nèi)和類外實現(xiàn)
全局函數(shù)類內(nèi)實現(xiàn)-直接在類內(nèi)聲明友元即可
全局函數(shù)類外實現(xiàn)-需要提前讓編譯器知道全局函數(shù)的存在文章來源:http://www.zghlxwxcb.cn/news/detail-603820.html
#include <iostream>
using namespace std;
#include <string>
//通過全局函數(shù) 打印Person信息
//提前讓編譯器知道Person類存在
template<class T1, class T2>
class Person;
//類外實現(xiàn)
template<class T1, class T2>
void printPerson2(Person<T1, T2> p)
{
cout << "類外實現(xiàn)--姓名:" << p.m_Name << " 年齡:" << p.m_Age << endl;
}
template<class T1, class T2>
class Person
{
//全局函數(shù) 類內(nèi)實現(xiàn)
friend void printPerson(Person<T1, T2> p)
{
cout << "姓名:" << p.m_Name << " 年齡:" << p.m_Age << endl;
}
//全局函數(shù) 類外實現(xiàn)
//加空模板參數(shù)列表
//如果全局函數(shù) 是類外實現(xiàn),需要讓編譯器提前知道這個函數(shù)的存在
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、全局函數(shù)在類內(nèi)實現(xiàn)
void test01()
{
Person<string, int>p("Tom", 20);
printPerson(p);
}
//2、全局函數(shù)在類外實現(xiàn)
void test02()
{
Person<string, int>p("Jerry", 20);
printPerson2(p);
}
int main()
{
test01();
return 0;
}
總結(jié):建議全局函數(shù)做類內(nèi)實現(xiàn),用法簡單,而且編譯器可以直接識別。文章來源地址http://www.zghlxwxcb.cn/news/detail-603820.html
到了這里,關(guān)于第一百一十三天學(xué)習(xí)記錄:C++提高:類模板(黑馬教學(xué)視頻)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!