C++中this指針詳解

1. this指針的用處:
  • 一個對象的this指針并不是對象本身的一部分,不會影響sizeof(對象)的結(jié)果。
  • this作用域是在類內(nèi)部,當(dāng)在類的非靜態(tài)成員函數(shù)中訪問類的非靜態(tài)成員的時(shí)候,編譯器會自動將對象本身的地址作為一個隱含參數(shù)傳遞給函數(shù),對各成員的訪問均通過this。例如,調(diào)用date.SetMonth(9) 便被轉(zhuǎn)換成SetMonth(&date, 9),this幫助完成了這一轉(zhuǎn)換 。
2. this指針的使用:
  • 一種情況是,在類的非靜態(tài)成員函數(shù)中返回類對象本身時(shí),直接使用return *this
  • 另一種情況是,當(dāng)參數(shù)與成員變量名相同時(shí),如this->n=n而不能用n=n
3. this指針程序示例:
#include<iostream>
using namespace std;
class Point
{
  private:
  int x,y;
  public:
  Point(int a,int b)
  {
    x=a;
    y=b;
  }
  void MovePoint(int a,int b)
  {
    x+=a;
    y+=b;
  }
  void print()
  {
    cout<<"x="<<x<<"y="<<y<<endl;
  }  
};
int main()
{
  Point point1(10,10);
  point1.MovePoint(2,2);
  point1.print();
  return 0;

當(dāng)對象point1調(diào)用MovePoint(2,2)函數(shù)時(shí),即將point1對象的地址傳遞給了this指針。
MovePoint函數(shù)的原型應(yīng)該是 void MovePoint( Point *this, int a, int b);第一個參數(shù)是指向該類對象的一個指針,我們在定義成員函數(shù)時(shí)沒看見是因?yàn)檫@個參數(shù)在類中是隱含的。這樣point1的地址傳遞給了this,所以在MovePoint函數(shù)中便顯式的寫成:void MovePoint(int a, int b) { this->x +=a; this-> y+= b;}
可以知道,point1調(diào)用該函數(shù)后,也就是point1的數(shù)據(jù)成員被調(diào)用并更新了值。

4. 類的this指針有以下特點(diǎn):

(1). this只能在成員函數(shù)中使用。
全局函數(shù)、靜態(tài)函數(shù)都不能使用this.
實(shí)際上,成員函數(shù)默認(rèn)第一個參數(shù)為T * const this如:

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

其中,func的原型在編譯器看來應(yīng)該是:int func(A * const this,int p);

(2). 由此可見,this在成員函數(shù)的開始前構(gòu)造,在成員函數(shù)的結(jié)束后清除。
這個生命周期同任何一個函數(shù)的參數(shù)是一樣的,沒有任何區(qū)別。
當(dāng)調(diào)用一個類的成員函數(shù)時(shí),編譯器將類的指針作為函數(shù)的this參數(shù)傳遞進(jìn)去。如:

A a;
a.func(10);```
此處,編譯器將會編譯成:
`A::func(&a,10);`
看起來和靜態(tài)函數(shù)沒差別,對嗎?不過,區(qū)別還是有的。編譯器通常會對this指針做一些優(yōu)化,因此,this指針的傳遞效率比較高--如VC通常是通過ecx寄存器傳遞this參數(shù)的。

**(3). 幾個this指針的易混問題。**
**A. this指針是什么時(shí)候創(chuàng)建的?**
this在成員函數(shù)的開始執(zhí)行前構(gòu)造,在成員的執(zhí)行結(jié)束后清除。
但是如果class或者struct里面沒有方法的話,它們是沒有構(gòu)造函數(shù)的,只能當(dāng)做C的struct使用。采用 TYPE xx的方式定義的話,在棧里分配內(nèi)存,這時(shí)候this指針的值就是這塊內(nèi)存的地址。采用new的方式 創(chuàng)建對象的話,在堆里分配內(nèi)存,new操作符通過eax返回分配 的地址,然后設(shè)置給指針變量。之后去調(diào) 用構(gòu)造函數(shù)(如果有構(gòu)造函數(shù)的話),這時(shí)將這個內(nèi)存塊的地址傳給ecx,之后構(gòu)造函數(shù)里面怎么處理請 看上面的回答。

**B. this指針存放在何處?堆、棧、全局變量,還是其他?**
this指針會因編譯器不同而有不同的放置位置。可能是棧,也可能是寄存器,甚至全局變量。在匯編級 別里面,一個值只會以3種形式出現(xiàn):立即數(shù)、寄存器值和內(nèi)存變量值。不是存放在寄存器就是存放在內(nèi) 存中,它們并不是和高級語言變量對應(yīng)的。

**C. this指針是如何傳遞類中的函數(shù)的?綁定?還是在函數(shù)參數(shù)的首參數(shù)就是this指針?那么,this指針 又是如何找到“類實(shí)例后函數(shù)的”?**
大多數(shù)編譯器通過ecx寄存器傳遞this指針。事實(shí)上,這也是一個潛規(guī)則。一般來說,不同編譯器都會遵從一致的傳參規(guī)則,否則不同編譯器產(chǎn)生的obj就無法匹配了。
在call之前,編譯器會把對應(yīng)的對象地址放到eax中。this是通過函數(shù)參數(shù)的首參來傳遞的。this指針在調(diào)用之前生成,至于“類實(shí)例后函數(shù)”,沒有這個說法。類在實(shí)例化時(shí),只分配類中的變量空間,并沒有為函數(shù)分配空間。自從類的函數(shù)定義完成后,它就在那兒,不會跑的。

**D. this指針是如何訪問類中的變量的?**
如果不是類,而是結(jié)構(gòu)體的話,那么,如何通過結(jié)構(gòu)指針來訪問結(jié)構(gòu)中的變量呢?如果你明白這一點(diǎn)的話,就很容易理解這個問題了。 
在C++中 ,類和結(jié)構(gòu)是只有一個區(qū)別的:類的成員默認(rèn)是private,而結(jié)構(gòu)是public。
this是類的指針,如果換成結(jié)構(gòu),那this就是結(jié)構(gòu)的指針了。 
 
**E. 我們只有獲得一個對象后,才能通過對象使用this指針。如果我們知道一個對象this指針的位置,可以直接使用嗎?**
this指針只有在成員函數(shù)中才有定義。因此,你獲得一個對象后,也不能通過對象使用this指針。所以,我們無法知道一個對象的this指針的位置(只有在成員函數(shù)里才有this指針的位置)。當(dāng)然,在成員函數(shù)里,你是可以知道this指針的位置的(可以通過&this獲得),也可以直接使用它。

**F. 每個類編譯后,是否創(chuàng)建一個類中函數(shù)表保存函數(shù)指針,以便用來調(diào)用函數(shù)?**
普通的類函數(shù)(不論是成員函數(shù),還是靜態(tài)函數(shù))都不會創(chuàng)建一個函數(shù)表來保存函數(shù)指針。只有虛函數(shù)才會被放到函數(shù)表中。但是,即使是虛函數(shù),如果編譯器能明確知道調(diào)用的是哪個函數(shù),編譯器就不會通過函數(shù)表中的指針來間接調(diào)用,而是會直接調(diào)用該函數(shù)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內(nèi)容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,532評論 1 51
  • C++文件 例:從文件income. in中讀入收入直到文件結(jié)束,并將收入和稅金輸出到文件tax. out。 檢查...
    SeanC52111閱讀 2,822評論 0 3
  • 重新系統(tǒng)學(xué)習(xí)下C++;但是還是少了好多知識點(diǎn);socket;unix;stl;boost等; C++ 教程 | 菜...
    kakukeme閱讀 19,979評論 0 50
  • 1. 結(jié)構(gòu)體和共同體的區(qū)別。 定義: 結(jié)構(gòu)體struct:把不同類型的數(shù)據(jù)組合成一個整體,自定義類型。共同體uni...
    breakfy閱讀 2,137評論 0 22
  • 那個純真年代,我們滿頭滿腦地憧憬,沒天沒地地談?wù)f,無日無夜地夢見; 如今現(xiàn)實(shí)生活,我們無窮無盡的愁思,全心全意的尋...
    何心婷閱讀 568評論 0 9