C++中的模板類(lèi)繼承和成員訪問(wèn)問(wèn)題
C++模板類(lèi)繼承和成員訪問(wèn)
c++中聲明一個(gè)模板類(lèi)及子類(lèi),在子類(lèi)中如果需要訪問(wèn)父類(lèi)的protected變量,需要使用父類(lèi)的類(lèi)作用域限定符,否則會(huì)報(bào)“identifier not found”錯(cuò)誤。
例如:
template<typename T>
class A
{
protected:
?? ?int a;
};
?
template<typename T>
//模板的繼承,基類(lèi)需要指定模板參數(shù)
class B : public A<T>
{
public:
?? ?void func()
?? ?{
? ? ? ? //此處必須使用A::a來(lái)訪問(wèn);否則會(huì)找不到a的定義
? ? ? ? //如果不是模板類(lèi),顯然可以直接使用a來(lái)訪問(wèn)
?? ??? ?cout << A::a << endl;
?? ?}
};模板函數(shù)的內(nèi)部類(lèi)繼承時(shí),也是類(lèi)似的。
例如:
template<typename T>
class outer
{
public:
?? ?class innerBase
?? ?{
?? ?protected:
?? ??? ?T a;
?? ?};
?
? ? //在模板類(lèi)內(nèi)部繼承相同范圍內(nèi)的基類(lèi),基類(lèi)能指定模板參數(shù)(內(nèi)部類(lèi)默認(rèn)使用外部類(lèi)的模板參數(shù))
? ? //如果繼承其他的模板類(lèi),則需要指定模板參數(shù);內(nèi)部類(lèi)也可以定義自己的模板參數(shù)
?? ?class innerDrive : public innerBase
?? ?{
?? ?public:
?? ??? ?void func()
?? ??? ?{
? ? ? ? ? ? //此處必須使用innerBase::a(或者使用outer::innerBase::a)來(lái)訪問(wèn)a
? ? ? ? ? ? //否則無(wú)法找到a的定義
?? ??? ??? ?cout << innerBase::a << endl;
?? ??? ?}
?? ?};
};類(lèi)、類(lèi)模板的protected成員(受保護(hù))繼承規(guī)則
如下,為基類(lèi)模板和派生類(lèi)模板的繼承層次:
//基類(lèi)模板
template<typename T>
class D0 {
protected:
int testi;
double testdouble;
};
//派生類(lèi)模板
template<typename T>
class D1 :public D0 {
public:
};編譯時(shí)報(bào)錯(cuò)如下:

原因是派生類(lèi)只能繼承類(lèi),而不能繼承類(lèi)模板,解決措施就是D0后添加模板類(lèi)型參數(shù),如下:
//基類(lèi)模板
template<typename T>
class D0 {
protected:
int testi;
double testdouble;
};
//派生類(lèi)模板
template<typename T>
class D1 :public D0<T> {//修改處,D0后增加了<T>
public:
};現(xiàn)在開(kāi)始在派生類(lèi)中使用繼承自基類(lèi)的protected成員:
//基類(lèi)模板
template<typename T>
class D0 {
protected:
int testi;
double testdouble;
};
//派生類(lèi)模板
template<typename T>
class D1 :public D0<T> {
public:
D1():testi(0) { }//添加了一行使用繼承自基類(lèi)的protected成員的語(yǔ)句
};編譯時(shí)報(bào)錯(cuò)如下:

原因在于,派生類(lèi)只能訪問(wèn)具體某個(gè)類(lèi)的protected成員,不能訪問(wèn)一個(gè)模板的protected成員。
testi未指定究竟是繼承自哪個(gè)類(lèi)的protected成員,解決措施措施如下:
(1)如果想訪問(wèn)的是繼承自D0類(lèi)的testi成員,則修改如下:
//基類(lèi)模板
template<typename T>
class D0 {
protected:
int testi;
double testdouble;
};
//派生類(lèi)模板
template<typename T>
class D1 :public D0<T> {
public:
D1():D0<int>::testi(0) { }//訪問(wèn)繼承自D0<int>的protected成員
};(2)如果是想訪問(wèn)跟隨實(shí)例化D1的類(lèi)型T,則修改如下:
//基類(lèi)模板
template<typename T>
class D0 {
protected:
int testi;
double testdouble;
};
//派生類(lèi)模板
template<typename T>
class D1 :public D0<T> {
public:
D1():D0<T>::testi(0) { }//如果D1被實(shí)例化時(shí)為D1<int>,那么就訪問(wèn)繼承自D0<int>的protected成員
//如果D1被實(shí)例化時(shí)為D1<doublie>,那么就訪問(wèn)繼承自D0<double>的protected成員
//如果D1被實(shí)例化時(shí)為D1<string>,那么就訪問(wèn)繼承自D0<string>的protected成員
//…………………………………………
};(2.1)也就是說(shuō)T會(huì)跟隨實(shí)例化D1模板的類(lèi)型而變化。
小結(jié)一下:
(1)派生類(lèi)不能直接使用基類(lèi)模板的protected成員,必須指定是使用
具體哪個(gè)基類(lèi)的protected成員。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Qt 使用QDialog實(shí)現(xiàn)界面遮罩的示例(蒙版)
界面遮罩在很多時(shí)候都可以用到,例如彈窗,本文主要介紹了Qt 使用QDialog實(shí)現(xiàn)界面遮罩的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04
基于C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲
這篇文章主要為大家詳細(xì)介紹了基于C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05
基于樹(shù)莓派實(shí)現(xiàn)播放MP3音樂(lè)
這篇文章主要為大家詳細(xì)介紹了基于樹(shù)莓派實(shí)現(xiàn)播放MP3音樂(lè),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06

