一文詳解C++中隱含的this指針
一、this指針的引出
我們先來定義一個日期類Date
,下面這段代碼執(zhí)行的結果是什么呢?
class Date { public: void Init(int year, int month, int day) { _year = year; _month = month; _day = day; } void print() { cout << _year << "-" << _month << "-" << _day << endl; } private: int _year; int _month; int _day; }; int main() { Date d1, d2; d1.Init(2022, 5, 11); d2.Init(2022, 5, 12); d1.print(); d2.print(); return 0; }
可以看到分別打印出了兩個日期,它是怎么知道改打印哪個的?
我們來分析一下,先看一下匯編代碼,看一看
- 我們看到上面的代碼是調(diào)用的同一個函數(shù),那么編譯器是如何知道那兩個日期的?
- 其實C++里有一個隱形的this指針,在微軟的官方文檔也有說明
- 在使用函數(shù)的時候其實里面傳了一個地址,然后有一個隱的this指針來接收
原形是這樣:
- 那為什么這里報錯了呢?
- 因為不必要寫,這個是隱含的~~,我們可以直接在類里面使用
二、this指針的特性
剛剛上面也給你看了原形,細心的烙鐵已經(jīng)發(fā)現(xiàn)了,這個this指針是有一個const修飾的,而且這個const是在*
的右邊
這里的const修飾
- 到這里就得出的this本身是不被修改的,但是做指向的值是可以被修改
- 我們可以在類中打印一下this指針的地址,再打印一下d1和d2的地址,我們來看一下:
- 得到結果就是this指針指向一個指向當前對象的指針
- 我們還可以下面這樣,是不會報錯的,但是不能向上面直接在形參就寫上
特點:
1、形參和實參的位置,我們不能顯示寫
2、函數(shù)內(nèi)部可以使用
最后總結一下:
- this指針的類型:類型 *const,即成員函數(shù)中,不能給this指針賦值。
- 只能在“成員函數(shù)”的內(nèi)部使用this指針本質(zhì)上是“成員函數(shù)”的形參,當對象調(diào)用成員函數(shù)時,將對象地址作為實參傳遞給this形參。所以對象中不存儲this指針。
- this指針是“成員函數(shù)”第一個隱含的指針形參,一般情況由編譯器通過ecx寄存器自動傳遞,不需要用戶傳遞
【面試題】
this指針存在哪里?
a、堆 b、棧 c、靜態(tài)區(qū) d、常量區(qū) e、對象里面
- 首先排除
e
,因為我們知道,在算類里的對象的時候是沒有算this指針的大小,所以排除e
- C++的const變量不是在常量區(qū),可以看到這兩個地址是挨著的
那么什么在常量區(qū)呢?是const修飾的值在常量區(qū),這個指針變量在棧區(qū),指向了這個常量區(qū)的字符串的首字符,所以d
也就排除
- c就更不可能了,static和全局的才在靜態(tài)區(qū)
- a也可以排除,因為malloc的才在堆,這里不是malloc,所以排除
- 最后就是在棧上,因為是一個形參(有些編譯比如vs可能會用寄存器存儲)。不同的編譯器放在不同的位置,可能是棧,也可能是寄存器,(VC++編譯器是放在ECX中,其它編譯器有可能不同,也就是成員函數(shù)的其它參數(shù)正常都是存放在棧中。而this指針參數(shù)則是存放在寄存器中。)
- 打開匯編我們也可以看到這里的lea就是load effective address【加載有效地址】,是存在ecx的值加載到 [d1] 里
this指針可以為空嗎?
下面我們來看兩道題來解決這個問題的答案~
第一道:下面程序編譯運行結果是? A、編譯報錯 B、運行崩潰 C、正常運行
class A { public: void Print() { cout << "Print()" << endl; } private: int _a; }; int main() { A* p = nullptr; p->Print(); return 0; }
已經(jīng)完美運行了,因為我這里沒有訪問類里的對象,所以可以正常運行
第二道:下面程序編譯運行結果是? A、編譯報錯 B、運行崩潰 C、正常運行
class A { public: void PrintA() { cout << _a << endl; } private: int _a; }; int main() { A* p = nullptr; p->PrintA(); return 0; }
這里引發(fā)了空指針,因為我需要打印這里的_a
,就要找到那塊空間
也就可以寫成這樣,this指針是空指針,解引用就會報錯
所以this指針是可以為空的,只要在成員函數(shù)內(nèi)部不訪問其內(nèi)容,程序可以正常執(zhí)行的。
以上就是一文詳解C++中隱含的this指針的詳細內(nèi)容,更多關于C++ this指針的資料請關注腳本之家其它相關文章!
相關文章
C++連接mysql數(shù)據(jù)庫并讀取數(shù)據(jù)的具體步驟
在實際開發(fā)中我們經(jīng)常需要對數(shù)據(jù)庫進行訪問,針對不同類型的數(shù)據(jù)庫(如MySQL、sqLite、Access、Excel等),如果采用不同的方法進行連接,會把我們搞崩潰,下面這篇文章主要給大家介紹了關于C++連接mysql數(shù)據(jù)庫并讀取數(shù)據(jù)的具體步驟,需要的朋友可以參考下2023-04-04解析C++的線性表鏈式存儲設計與相關的API實現(xiàn)
這篇文章主要介紹了解析C++中的線性表鏈式存儲設計與相關的API實現(xiàn),文中的實例很好地體現(xiàn)了如何創(chuàng)建和遍歷鏈表等基本操作,需要的朋友可以參考下2016-03-03