前言
在用C++進行面向對象編程時,this指針是一個人盡皆知的東西。但我們真的清楚它嗎?下面我們對它的存在意義和使用方法一一進行探討。
this指針
存在意義:我們為何需要this指針?
看一個簡單的例子
#include <iostream>
using namespace std;
class MyClass
{
protected:
int a;
public:
MyClass(int a) :a(a)
{}
void setA(int a)
{
this->a = a;
}
int getA() const
{
return a;
}
};
int main()
{
MyClass my1(0);
MyClass my2(1);
my1.setA(2);
my2.setA(3);
cout << "my1::a = " << my1.getA() << endl;
cout << "my2::a = " << my2.getA() << endl;
cin.get();
return 0;
}
運行
這個例子實在是太簡單了!大家用腳指頭都能看明白。我們需要深入思考下:
1.setA方法中明明沒有this形參,為何在方法體中可以使用this?
答:this形參是隱式定義的,它代表當前對象的內存地址。我們不寫,並不代表它不存在。
2.在設計setA方法時,我故意把方法形參(int a)和類成員變量(int MyClass::a)設計成同名的。以至於function body中必須寫成 this->a=a;才能完成賦值。若把形參寫成不同名的,比如int A,是否可以省略this?
答:可以的。但本質上還是this->a=A;還是那句:我們不寫,並不代表它不存在。編譯器在進行編譯時,會自動把“a=A”改為“this->a=A;”。
3.從以上兩個問題還沒弄清this的存在意義嗎?那就多說一句,程序在內存中的存儲原理:代碼區是公共的,靜態變量是公共的。公共是只有一份的意思。
前者是公共的理由是:節約內存。後者是公共的理由是:邏輯上本該如此!(靜態變量的存在意義)
總之,類MyClass的任何對象在調用setA方法時,都是調用同一份代碼。但為何會有不同的效果呢?對象my1在調用setA時,是對my1.a進行賦值。對象my2在調用setA時,是對my2.a賦值。它們執行的代碼相同,卻不會亂掉,就是因為this指針的存在!
這就完了嗎?還沒有,我們需要進一步指出:this指針隱式定義於方法形參中。那麼它的位置是?這不好說,我的推測:就是第一個形參。我的理由:方法調用時,傳入的實參是從右向左入棧的,出棧時,第一個位置的參數當然就最先出棧。(若有不同的看法,歡迎討論!)以下的討論就暫且基於這種假設。
所以,setA(int a);本質上應該是 setA(MyClass * const this, int a);
my1.setA(2);本質上應該是 my1.setA(&my1, 2);
再深入,細心的你會發現,我寫的是 MyClass * const this,而不是 MyClass * this,多了一個const,為何?這當然也是有理由的!
理由很簡單:若this不是const的,則可以隨意更改this的指向,如下代碼:
void setA(int a)
{
this = &my;
this->a = a;
}
當然,這樣的代碼肯定是通不過編譯的。每次對setA的調用都變成了對my.a的賦值。
總結:默認情況下,this的類型是指向類類型非常量版本的常量指針。(《C++Primer》)
還沒完,我們還得繼續深入……
const成員函數是怎麼一回事?它和this有聯系嗎?
我們知道,const成員函數是不可以對成員變量進行修改的。那它是如何做到的呢?
原因:const對成員函數的修飾,就是對this的修飾。
上面的例子中的int getA()const;本質上是 int getA(MyClass const * const this);
至此,真相終於大白。
------------------------------分割線------------------------------
C++ Primer Plus 第6版 中文版 清晰有書簽PDF+源代碼 http://www.linuxidc.com/Linux/2014-05/101227.htm
讀C++ Primer 之構造函數陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm
讀C++ Primer 之智能指針 http://www.linuxidc.com/Linux/2011-08/40177.htm
讀C++ Primer 之句柄類 http://www.linuxidc.com/Linux/2011-08/40175.htm
將C語言梳理一下,分布在以下10個章節中: