很多程式員 C 語言基礎不好,結果用了好多年 C++ ,還是知其然而不知是以然,往往經不起别人一問 ”xx 機制怎麼實作的 ” ? this 指針就是 C++ 的基礎機制之一。
struct到class進化的第一步
設想我們是十幾年前C++的設計者,從C的struct怎麼進化到C++的class?
struct裡可以用函數指針作成員變量,并通過諸如xxx->fun()的形式調用,但和class成員函數相比:1)不能在struct内部定義函數;2)不能在struct成員函數内直接通路struct的其他成員變量。這兩點形式上的局限使得struct無法直接展現面向對象的思想。怎麼解決呢?問題1)struct(class)實作内部定義函數由編譯器name mangling機制完成,後面講述,這裡講第2點。
struct Base
{
int a,b;
void add_mem() { return(a+b); };
};
假設可在struct内定義函數,那要在函數裡直接通路成員a,b,順理成章的辦法就是設法把指向結構體變量自身的指針傳到成員函數内部,即由編譯器把函數add_mem()變成add_mem(void *this){ return(this->a+this->b); }
這個隐含的包含對象位址的參數就是this指針,C++編譯器就能自動擷取對象位址賦給this,再通過一個隐含參數把this傳進類的非靜态成員函數,于是函數内部通路類的非靜态成員變量就可以借助于this,如:
class Point
{
int x, y, z;
public:
Point(inta, int b, int c) { x=a; y=b; z=c; }
voidMovePoint( int a, int b, int c){ x+=a; y+=b; z+=c; }
};
void main( )
{
Pointpoint1( 0,0,0);
point1.MovePoint(1,1,1);
}
MovePoint真正原型是void MovePoint( Point *this,int a, int b, int c){ this.x+=a; this.y+=b; this.z+=c; }。對象point1調用MovePoint(1,1,1)時,就把point1的位址傳給了this指針,調用point1.MovePoint(1,1,1)相當于point1.MovePoint (&point1,1,1,1 )
顯式使用this指針的場合:
this指針保留了成員函數所屬類的執行個體對象位址,形式上它通常是隐含的,編譯器編譯時會自動在引用成員變量的每個表達式中插入this指針。不過某些特殊場合也需要顯式使用它:
情況一:在類的非靜态成員函數中傳回類對象本身時,需要用return*this。
情況二:當函數參數與成員變量同名,如:
class Date
{
int year, month, day;
public:
setYear(int year) { year=year }
……
};
setYear裡無法識别哪個year是類成員,哪個是參數。是以這裡就需要借用this指針:
setYear( int year) { this->year = year; }這樣就不會混淆了。
注意:
1. this指針僅作用于類的非靜态成員函數内部,靜态成員函數内沒有this指針。
2. this指針不是對象本身的一部分,不會影響sizeof(對象)結果。