條款43 學習處理模板化基類內的名稱

2021-05-03 21:08:17 字數 2390 閱讀 7680

條款43:學習處理模板化基類內的名稱

(know how to access names in templatized base classes.)

內容:現在我們接到乙個編碼任務,任務要求我們的目標程式能夠傳送資訊到不同的公司去.這裡的資訊可以分為:被譯成密碼的資訊和未經加工資訊明文資訊.我們分析了任務以後認為,在目標程式的編譯期間我們就可以決定哪乙個資訊傳送至哪一家公司.所以我們採用了template來實現,大概的偽**實現如下:

class companya;

class companyb;

... //其它公司的classes.

class msginfo;//這個class為將來生產儲存資訊

template

class msgsender

void sendsecret(const msginfo& info) //這裡呼叫的是c.sendencrypted.

};上面的設計屬於乙個良好的設計.現在我們又需要另外一種msgsender,它的特殊之處在於,在每次傳送資訊時,它能夠log某些資訊.顯然將這個類視為msgsender的乙個子類將是乙個不錯的選擇:

template

class loggingmsgsender:public msgsender

...  

};這樣的**看起來沒用什麼可以指責的地方,但編譯器卻不讓其通過編譯.此時的編譯器丟擲了"sendclear不存在"的抱怨.可sendclear明顯就在base class內部啊?鬱悶,這是為什麼倪?別急,我來解釋一下:當編譯器遇到loggingmsgsender定義式時,由於company是乙個template引數,不到loggingmsgsender被具現化的時候,編譯器是無法知道company是什麼的.由於無法知道company是什麼,那麼它就無法確定msgsender是什麼,也就無法獲知其否有個sendclear函式. 停一下,你可能現在對我的解釋會有乙個問題:為什麼根據template company就不能確定company是什麼了呢?template company不是有宣告式嘛!在這裡我提出:我們不能根據一般性模板類的宣告式來確定具現化類具有的操作,因為模板類有個特化宣告版本的問題.為了讓問題具體化,假設現在有另外乙個companyz堅持使用加密通訊:

class companyz;

現在的問題是:一般性的模板類msgsender宣告對companyz並不適用,因為那個template提供了乙個sendclear函式(內部呼叫sendcleartext函式),而這對companyz物件不合理.欲矯正這個問題,我們可以針對companyz產生乙個msgsender特化版:

template<>

class msgsender //只提供sendsecret方法

...};

好了,我們再次來看loggingmsgsender::sendclearmsg:

tempalte

void loggingmsgsend::(const msginfo& info)

噠噠噠噠,問題來了吧!這就是c++拒絕這個呼叫的原因:它知道base class template有可能被特化,而那個特化版本可能不提供和一般性template相同的介面.就某種意義而已,當我們從object oriented c++跨進template c++,繼承就不像以前那麼暢行無阻了.

麻煩點就麻煩點,問題終歸還是要解決的.我們有以下三個方法來解決此類問題:

方法一:在base class函式呼叫動作之前加上"this->":

template

void loggingmsgsender::sendclearmsg(const msginfo& info)

方法二:使用using宣告式.

template

class loggingmsgsender:public msgsender

};方法三:明明白白指出被呼叫函式位於base class內:

template

class loggingmsgsender:public msgsender

...};

不過此方法有乙個很明顯的暇疵:如果被呼叫的是virtual函式,上述的明確資格修飾會關閉"virtual繫結行為".

根本而言,本條款**的是,面對"指涉base class members"之無效references,編譯器的診斷時間可能發生在早期(當解析derived class template的定義式時),也可能發生在晚期(當那些template被特定之template實參具現化時).c++的政策是寧願較早診斷,這就是為什麼"當base classes從template 中被具現化時"它假設它對那些base classes的內容毫無所悉的緣故.

請記住:

■ 可在derived class templates內通過"this->"指涉base class templates內的成員名稱,或由乙個明白寫出"base class資格修飾符"完成.

條款43 學習處理模板化基類的名稱

先看程式 class a templateclass drivedusea public usea int main 1.在基類函式呼叫動作之前加上this this useafunc 2.使用using宣告 templateclass drivedusea public usea 3.明確指出被調...

條款43 學習處理模版化基類內的名稱

考慮以下 功能為傳送不同資訊至不同部門,採用模版方法。class companya class companyb 其他公司的類class msginfo 用來儲存資訊,以備用 templateclass msgsend void sendsecret const msginfo info 格式同上 ...

43 學習處理模版化基類內的名稱

1 考慮下面的場景,有個類模版templatebox 內部有個方法 現在子類templateclass bigbox public box bigbox內部使用方法 考慮出現什麼問題?2 首先一點,類模版產生出來的類之間,沒有關係。也就是box與box沒有關係。通過指定模版實參,可以產生不同的模板類...