2020-02-19 C++提高編程02-基本框架

1.3類模板

1.3.1類模板語法

作用:建立一個通用類,類中的成員 數(shù)據(jù)類型可以不具體指定,用一個虛擬的類型來代表;

語法:?

template<class T>

解釋:

template :聲明創(chuàng)建模板

class/typename :表明其后面的符號是一種數(shù)據(jù)類型

T? :通用數(shù)據(jù)類型,通常為大寫字母

示例:

template<class NameType,class AgeType>

class Person

{

public:

Person(NameType name, AgeType age)

{

this->m_Name = name;

this->m_Age = age;

}

NameType m_Name;

AgeType m_Age;

};

1.3.2類模板與函數(shù)模板區(qū)別

1.類模板沒有自動類型推導(dǎo)的使用方式;

2.類模板在模板參數(shù)列表中可以有默認參數(shù);

示例:

template<class NameType, class AgeType=int>

class Person

{

public:

Person(NameType name, AgeType age)

{

this->m_Name = name;

this->m_Age = age;

}

NameType m_Name;

AgeType m_Age;

};

void test01()

{

//無法使用自動類型推導(dǎo)

//Person p("Mike", 20);//error

Person<string,int>p("Mike", 20);

}

void test02()

{

Person<string>p("Mike", 20);//ok 因為模板參數(shù)列表設(shè)置了默認參數(shù)

}


1.3.3類模板中成員函數(shù)創(chuàng)建時機

類模板中成員函數(shù)和普通類中成員函數(shù)創(chuàng)建時機是有區(qū)別的:

1.普通類中成員函數(shù)一開始就可以創(chuàng)建;

2.類模板中成員函數(shù)在調(diào)用時才創(chuàng)建;

示例:

class Person1

{

public:

void showPerson1()

{

cout << "showPerson1()" << endl;

}

};

class Person2

{

public:

void showPerson2()

{

cout << "showPerson2()" << endl;

}

};

template <class T>

class MyClass

{

public:

T obj;

//類模板中的成員函數(shù),并不是一開始就創(chuàng)建的,而是在模板調(diào)用時再生成

void func1()

{

obj.showPerson1();

}

void func2()

{

obj.showPerson2();

}

};

void test01()

{

MyClass<Person1> m;

m.func1();

//m.func2();//error

//編譯會出錯,說明函數(shù)調(diào)用才會去創(chuàng)建成員函數(shù)

}

1.3.4類模板對象做函數(shù)參數(shù)

要點:類模板實例化出的對象,向函數(shù)傳參的方式

一共有三種傳入方式:

1.指定傳入的類型? ---直接顯示對象的數(shù)據(jù)類型

2.參數(shù)模板化? ? ---將對象中的參數(shù)變?yōu)槟0暹M行傳遞

3.整個類模板化? ? ---將這個對象類型 模板化進行傳遞、

示例:

template <class T1, class T2>

class Person

{

public:

Person(T1 name, T2 age)

{

this->m_Name = name;

this->m_Age = age;

}

void showPerson()

{

cout << "name: " << this->m_Name << endl

<< "age: " << this->m_Age << endl;

}

T1 m_Name;

T2 m_Age;

};

//1.指定傳入類型

void printPerson1(Person<string, int> &p)

{

p.showPerson();

}

void test01()

{

Person<string, int> p("Mike", 20);

printPerson1(p);

}

//2.參數(shù)模板化

template <class T1, class T2>

void printPerson2(Person<T1, T2> &p)

{

p.showPerson();

cout << "type of T1: " << typeid(T1).name() <<endl

<< "type of T2: " << typeid(T2).name() << endl;

}

void test02()

{

Person<string, int> p("Jack", 22);

printPerson2(p);

}

//3.這個類模板化

template <class T>

void printPerson3(T &p)

{

p.showPerson();

cout << "type of T: " << typeid(T).name() << endl;

}

void test03()

{

Person<string, int> p("Mary", 18);

printPerson3(p);

}

總結(jié):

1.通過類模板創(chuàng)建的對象,可以有三種方式向函數(shù)中進行傳參;

2.第一種指定傳入類型 使用的比較廣泛;

1.3.5類模板與繼承

1.當子類繼承的父類是一個類模板時,子類在聲明時,要指定出父類中T的類型;

2.如果不指定,編譯器無法給子類分配內(nèi)存;

3.如果想要靈活指定出父類中T的類型,子類也需要變?yōu)轭惸0澹?/p>

示例:

template <class T>

class Base

{

public:

T m;

};

class Son//:public Base//error 必須要知道父類中T類型,才能繼承給子類

:public Base<int>{};

//如果想要靈活指定出父類中T的類型,子類也需要變?yōu)轭惸0?/p>

template <class T1,class T2>

class Son2:public Base<T2>

{

public:

T1 obj;

};

void test02()

{

Son2<int,char> s2;

}

總結(jié):如果父類是類模板,子類需要指定出父類中T的數(shù)據(jù)類型

1.3.6類模板成員函數(shù)類外實現(xiàn)

示例:

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 << "name: " << this->m_Name << endl

<< "age: " << this->m_Age << endl;

}

總結(jié):

1.函數(shù)實現(xiàn)體前需要聲明是模板;

2.在類名之后加模板參數(shù)列表;

1.3.7類模板分文件編寫

問題:類模板中成員函數(shù)創(chuàng)建時機是在調(diào)用階段,導(dǎo)致分文件編寫時鏈接不到

解決:

1.直接包含.cpp源文件;

2.將聲明和實現(xiàn)寫到同一個文件中,并更改后綴名為 .hpp (約定名稱,而非強制)

注:主要采用第二種,將類模板成員函數(shù)寫到一起,并更改后綴為.hpp

示例:

1.person.hpp文件

#pragma once

#include <iostream>

#include <string>

using namespace std;

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 << "name: " << this->m_Name << endl

<< "age: " << this->m_Age << endl;

}

2.實現(xiàn)文件

#include "person.hpp"

...

1.3.8類模板與友元

要點:掌握類模板配合友元函數(shù)的類內(nèi)和類外實現(xiàn)

全局函數(shù)類內(nèi)實現(xiàn)-直接在類內(nèi)聲明友元即可;

全局函數(shù)類外實現(xiàn)-需要提前讓編譯器知道全局函數(shù)的存在;

示例:

1.類內(nèi)實現(xiàn)

template<class T1, class T2>

class Person

{

friend void printPerson(Person<T1, T2> p)

{

cout << "name: " << p.m_Name << endl

<< "age: " << p.m_Age << endl;

}

public:

Person(T1 name, T2 age)

{

this->m_Name = name;

this->m_Age = age;

}

private:

T1 m_Name;

T2 m_Age;

};

2.類外實現(xiàn)

//提前讓編譯器知道Person類存在

template<class T1, class T2>

class Person;

//提前讓編譯器知道這個全局函數(shù)的存在

//函數(shù)模板聲明

template<class T1, class T2>

void printPerson2(Person<T1, T2> p)

{

cout << "name: " << p.m_Name << endl

<< "age: " << p.m_Age << endl;

}

template<class T1, class T2>

class Person

{? ?

? ? //error 普通函數(shù)聲明 并非函數(shù)模板聲明

//friend void printPerson2(Person<T1, T2> p);

//如果全局函數(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;

};

總結(jié):建議全局函數(shù)做類內(nèi)實現(xiàn),用法簡單,而且編譯器可以直接識別;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容