C 之this指標與另一種「多型」

2021-06-20 00:03:57 字數 2358 閱讀 9458

一、 引入

定義乙個類的物件,首先系統已經給這個物件分配了空間,然後會呼叫建構函式(說明:假設存在建構函式--2010.9.5修正)。乙個類有多個物件,當程式中呼叫物件的某個函式時,有可能要訪問到這個物件的成員變數。而對於同乙個類的每乙個物件,都是共享同乙份類函式。物件有單獨的變數,但是沒有單獨的函式,所以當呼叫函式時,系統必須讓函式知道這是哪個物件的操作,從而確定成員變數是哪個物件的。這種用於對成員變數歸屬對像進行區分的東西,就叫做this指標。事實上它就是物件的位址,這一點從反彙編出來的**可以看到。

二、分析

1、測試**:

#includeusing namespace std;

/class a

{public:

a(char *szname)

{cout<

對編譯後的exe檔案,進行反彙編。反彙編工具為ollydbg。

程式在vc++6.0 32位作業系統上編譯、執行。

對編譯後的exe檔案,進行反彙編。反彙編工具為ollydbg。

2、反彙編分析

關鍵點截圖如下:

(1)從圖1可以發現this指標通過ecx暫存器,傳遞給了成員函式。this指標就是物件的位址。

圖 1 main函式

(2)從圖 2可以發現訪問物件的成員變數用的就是之前通過ecx傳入的this指標。

圖 2 show()函式

三、深入理解

通過截圖及相關的資料,可以很清晰的知道在呼叫建構函式、show()函式之前的那個ecx就是this指標,也就是說這是乙個驗證性的實驗,答案已經很清楚了,所要做的就是去動手體驗一下。但是,假如我不懂c++、我不懂什麼this指標,我一樣可以發現這個叫做「this指標」的東西。通過od的動態除錯,當顯示出了name時,逐步回溯可以發現name的源頭是ecx。od重新載入,檢視在進入show()函式之前ecx是**來的,最終可以一步步的發現,ecx就是乙個位址,這個位址裡邊的第乙個值也是乙個位址,指向一串字串。再往上分析,進入show()上邊的建構函式,可以發現裡邊有new操作,strcpy操作,這裡就發現了字串空間、內容的**。至此,基本就分析完了。

通過這個過程可以發現很多c++的知識。如:物件的空間是在呼叫建構函式之前就分配好了的;物件裡邊沒有函式;this指標通過暫存器ecx傳遞;通過宣告定義的物件它的空間分配在棧中;等等這些跟系統或者c++有關聯的知識。

但是,對於乙個不懂c++的人看來,上面一段的體會都是沒有的。從彙編指令看不出c++的思想,this指標不過是乙個位址;物件不過是一些空間;建構函式、析構函式以及其它的函式,也不過是一堆指令的集合。c++的同乙個類定義出來的多個物件,從彙編指令看來是這樣的:有很多塊位址空間,它們有相同的大小。當不同的物件呼叫成員函式時,在彙編指令看來是:它們都call同乙個位址,這個call指令其實裡邊是乙個jmp指令,用於跳向某個位置,在call指令之前一般都會把乙個位址放到ecx中,當然有時候會用堆疊或者其它暫存器。c++的繼承、多型、封裝,對彙編程式設計師來說是看不出有什麼神奇的,對於c++程式設計師來說那可就不同了,可以省去很多的工作,把很多事情都交給了編譯器,讓編譯器自動給你搞定。c++程式設計師所討論的物件及其眾多的特點、優點,最終還是變成了「低階」的指令,而且可能是效率低下的指令,即便如此,它的優點仍遠大於缺點,它讓程式設計變得容易、高效。

四、延伸

這就是多型,這種多型使得呼叫同乙個函式,因為傳遞引數的不同而顯示出差異,引數可以是基類物件或者眾多不同的子類物件。它們的差異是類與類之間的。

有虛函式的物件的記憶體布局,比沒有虛函式的物件多了乙個指向虛函式表的指標。因為虛函式的呼叫是通過虛函式表指標來實現的,所以有了多型。再考慮一下c++的this指標,乙個類中的成員函式,依據this指標來區分不同的物件,也就是說根據this指標實現了訪問不同的物件的成員變數。

這是否也是多型的一種表現?這裡所說的多型已經不是那個「父類指標指向子類物件」的教條了,而是體現在同乙個類的不同物件之間,呼叫同乙個成員函式,依據引數「this指標」來實現訪問不同的物件的成員變數。成員函式訪問成員變數,在編譯期無法確定它訪問的成員變數在哪乙個位址的,只有到了執行期依據this指標才能確定訪問的位址。這一點很類似於類的多型:以基類指標為引數的函式裡呼叫了某個基類的虛成員函式,在編譯期無法確定程式執行時呼叫的會是哪個類的物件,只有到了執行期才確定會呼叫哪個類的物件。

this指標識別了同乙個類的不同的物件,換句話說,this指標使得成員函式可以訪問同乙個類的不同物件。再深入一點,this指標使得成員函式會因為this指標的不同而訪問到了不同的成員變數。這也是多型吧,只是它是必然存在的多型,這種多型跟基類與派生類之間的多型是不同級別的多型,它不像一般的多型可以通過對使用虛函式的選擇來取捨,它是乙個類對應多個物件、多個物件共享乙份成員函式

另一種尊重

上中學的時候,有一節課印象非常深刻。老師問我們如果無意闖入乙個房間,發現房間裡有一位女士正在洗澡,這時應該怎麼辦?有同學回答就當什麼也沒看見,退出房間。還有同學回答 說聲對不起!女士。然後退出去。老師笑了笑說,還有更好的答案,那就是 對不起,先生!有一對結婚多年的夫妻,有一次出差在外的妻子有一件急事...

另一種勝利

另一種勝利 written by allen lee 剛才我的扣殺,出界了5.3厘公尺。雖然很可惜,但還是出界了,請確認下吧。幹 真是的,那些任性的傢伙!但是,到最後還只顧自己網球原則的正直笨蛋,和一定要用迴旋蛇標打中單人區的笨蛋,給我們看了場好比賽啊。龍崎 海棠和幹他們雖然輸了這場比賽,但他們堅持...

另一種table排序

click on the table header to sort in ascending order.last name first name birthday siblings smith john 7 12 1978 2johnson betty 10 15 1977 4henderson ...