天天看點

《C++面向對象高效程式設計(第2版)》——3.5 this 指針和名稱重整的進一步說明

本節書摘來自異步社群出版社《c++面向對象高效程式設計(第2版)》一書中的第3章,第3.5節,作者: 【美】kayshav dattatri,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

c++面向對象高效程式設計(第2版)

在前面介紹的實作中,我們有時使用this指針通路對象的資料成員。如第2章所述,成員函數中的this指針指向調用該成員函數的對象。在前述的main()程式中,如下代碼

`

a.push(i);`

通過a對象調用push成員函數。在push成員函數内部,this指針持有a對象的位址。以這樣的方式,成員函數可以通路對象内的任何元素(資料成員和成員函數)。如第2章所述,編譯器像實作其他函數那樣,實作每個成員函數,但是,每個成員函數應該可以通過某種方法通路調用它的對象。為達到這個目的,this指針将作為隐藏的參數傳遞給每個成員函數,且this指針通常是函數接收的第1個參數(其後是已聲明的其他參數)。假定push成員函數的實作如下:

tintstack();  // 普通的未重整名稱

__ct__9tintstackfv();  // 重整後的名稱<code>`</code>

同樣地,此處的9tintstack仍代表this指針的類型,f表明該函數為全局函數,v表明該函數不接受任何參數(void)。

其他的構造函數(如果有的話)也會包含參數,是以,它們确切的名稱應該不同。例如,複制構造函數應該是:

~tintstack();  // 未重整名稱

__dt__9tintstackfv();  // 重整名稱<code>`</code>

類似地,操作符函數也有經過特定編碼的重整名。例如,指派操作符被編碼成:

<code>__as__9tintstack();</code>

全局new()操作符以__nw開始,全局delete操作符以__dl開始。

語言中所有的操作符都有預定義的(pre-defined)編碼。

你可能會問,為什麼要知道關于名稱重整的這些細節?

想象一下,你實作了一個類,但忘記實作一些成員函數。編譯過程可能沒什麼問題,但連結器會對未定義的函數報錯。這些顯示在報錯資訊中的函數,看上去與你在類頭檔案3中的函數不一樣。現在,你徹底糊塗了!

這是因為名稱重整的緣故。連結器在報錯時絕不會列印原始的函數名,它隻會給出由編譯器提供的等價重整名。連結器對重整一無所知(至少到目前為止,我還未見過連結器了解此事),它隻會抱怨那些未定義的名稱。此時,如果了解一些名稱重整會對你有幫助。如果連結器列印出的名稱以 ct 開始,則說明出問題的是某個構造函數,這縮小了查找未定義成員函數的範圍。随着你編寫的c++代碼越來越多,重整名稱會成為你破譯報錯資訊的秘密武器!相信我。

    

警告:

記住,this指針是個非常神聖的指針。不能修改this指針,絕不能給它指派!需要在成員函數内修改<code>this</code>指針的情況非常少見,稍後将會介紹這樣的示例。

你可能也注意到,在每個成員函數内,我們并未用this指針通路資料成員。例如,在pop函數中,無需任何限定符,即可直接通路資料成員<code>_count</code>。無論何時在成員函數中使用資料成員的名稱,編譯器都會為其預先添加“this”限定符。是以,<code>_count</code>成為<code>this-&gt;_count</code>。除非我們明确需要指向對象的指針,否則不必顯式使用它。

樣式:

在本書中,隻要有可能出現混淆的地方,都會顯式使用this限定符。例如,在之前的指派操作符中,有如下語句:

<code>this-&gt;_count = source._count;</code>

也可以寫成:

<code>_count = source._count;  // 這樣寫也正确!</code>

但是,同一語句中,通過不同的對象多次用相同的名稱_count會令人困惑。是以,要顯式使用this限定符。

什麼時候必須使用this指針?當我們希望傳回對調用某函數的對象的引用時,必須使用*this。否則,如何顯式表示“我的對象”這個概念?另一種情況是(如前所述的指派操作符中),我們希望獲得對象的位址,也必須顯式使用this名稱。到目前為止,這是顯式使用this名稱最常見的兩種情況。

1一些編譯器用n和f差別near和far函數,即用n代表near函數,用f代表far函數。

2譯者注:arm指的是margaret a. ellis與bjarne stroustrup合著的書:annotated c++ reference manual。isbn 0-201-51459-1。

3盡管連結器(和開發環境)越來越智能,開發環境為使用者顯示未經重整的名稱也越來越普遍。但是,粗略了解一下名稱重整仍然有好處。

本文僅用于學習和交流目的,不代表異步社群觀點。非商業轉載請注明作譯者、出處,并保留本文的原始連結。

繼續閱讀