c++ this 指針知識點總結(一看就懂)

寫在前面

在c++編程的過程中,經常會用到this指針,this指針的用法究竟是怎麼樣的呢?今天就來一探究竟。

this指針

首先,關於this指針有這樣一段描述:當你進入一間房子時,你可以看到桌子、椅子等,但是你已經看不到房子的全貌了。
對於一個實例來說,你可以看到它的數據成員、成員函數,但是對於實例本身呢?
this指針是這樣一個指針,時時刻刻指向這個實例本身。

this指針容易混淆的幾點:
1、 this指針實質上是一個函數參數,只是編譯器隱藏形式的、語法層面上的參數。
this指針只能在成員函數中使用,全局函數、靜態函數都不能使用this指針。
實際上,成員函數默認第一個參數爲 T* const this。
如:

class A
{
	public:
	int func(int p) {};
};

其中,函數func的原型在編譯器看來應該是:

int func(A* const this, int p) {}

2、this指針在成員函數開始前構造,在成員函數結束後清除。

生命週期同任何一個函數的參數是一樣的,沒有任何區別。當調用一個成員函數時,編譯器將類的指針作爲this參數傳遞進去,如:

A a;
a.func(10);

此處編譯器會編譯爲:

A::func(&a, 10);

看起來似乎和靜態函數沒有什麼區別,實際上還是有區別的,編譯器通常會對於this指針做一些優化,this指針的傳遞效率比較高。

3、this指針並不佔用對象的空間

this相當於非靜態成員函數的一個隱函的參數,不佔對象的空間。它跟對象之間沒有包含關係,只是當前調用函數的對象被它指向而已。

所有成員函數的參數,不管是不是隱含的,都不會佔用對象的空間,只會佔用參數傳遞時的棧空間,或者直接佔用一個寄存器。

4、this指針是什麼時候創建的?

this在成員函數開始執行前構造,在成員執行結束後清除。
如果 class或者 struct裏面沒有方法的話,它們是沒有構造函數的,只能當作C的struct t使用。
採用 TYPE XX 的方式定義的話,在棧裏分配內存,這時候this指針的值就是這塊內存的地址。
採用new方式創建對象的話,在堆裏分配內存,new操作符通過eax返回分配的地址,然後設置給指針變量。之後去調用構造函數(如果有構造函數的話),這時將這個內存塊的地址傳給ecx

5、this指針存放在何處?堆、棧、還是其他?

this指針會因編譯器不同而有不同的放置位置。可能是堆、棧,也可能是寄存器。C++是一種靜態的語言,那麼對C++的分析應該從語法層面和實現層面兩個方面進行。

語法上,this是個指向對象的“常指針”,因此無法改變。它是一個指向相應對象的指針。所有對象共用的成員函數利用這個指針區別不同變量,也就是說,this是“不同對象共享相同成員函數”的保證

在實際應用的時候,this應該是個寄存器參數。這個不是語言規定的,而是“調用約定”,C++的默認調用約定是 _cdecl,也就是C風格的調用約定。該約定規定參數自右向左入棧,由調用方負責平衡堆棧。
對於成員函數,將對象的指針(即this指針)存入ecx中(有的書將這一點單獨分開,叫作 thiscall,但是這的確是 cdecl的一部分)。因爲這只是一個調用約定,不是語言的組成部分,不同編譯器自然可以自由發揮。但是現在的主流編譯器都是這麼做的。

6、this指針是如何傳遞給類中的函數的?綁定?還是在函數參數的首參數就是this指針?那麼,this指針又是如何找到“類實例後函數”的?

大多數編譯器通過ecx寄存器傳遞this指針。事實上,這也是一個潛規則。一般來說,不同編譯器都會遵從一致的傳參規則,否則不同編譯器產生的obj就無法匹配了。

7、我們只有獲得一個對象後,才能通過對象使用this指針。如果我們知道一個對象this指針的位置,可以直接使用嗎?

this指針只有在成員函數中オ有定義。因此,你獲得一個對象後,也不能通過對象使用this指針。所以,我們無法知道一個對象的this指針的位置(只有在成員函數裏纔有this指針的位置)。當然,在成員函數裏,你是可以知道this指針的位置的(可以通過&this獲得),也可以直接使用它。

複習

在瞭解了關於 this 的原理之後,這裏有一道題留給熱心網友:

Q: Please choose the right statement of "this" pointer:
A:"this" pointer can not be used in static functions.
B:"this" pointer can not be stored in Register.
C:"this" pointer is constructed before member function.
D:"this" pointer is not counted for cauculating the size of object.
E:"this" pointer is read only.

歡迎在評論區給出你的答案,額…另有錯誤之處歡迎指正!


參考自:程序員面試寶典—歐立奇

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章