this 指標


考慮下面這個類別:
  • Ball.h
#include <string>
using namespace std;

class Ball {
public:
Ball();
Ball(double, const char*);
Ball(double, string&);

double radius() {
return _radius;
}

string& name() {
return _name;
}

void radius(double radius) {
_radius = radius;
}

void name(const char *name) {
_name = name;
}

void name(string& name) {
_name = name;
}

double volumn() {
return (4 / 3 * 3.14159 * _radius * _radius * _radius);
}

private:
double _radius; // 半徑
string _name; // 名稱
};

當您使用Ball類別新增兩個物件b1(1, "RBall")與b2(2, "GBall")時,b1與b2會各自擁有自己的_radius與_name資料成員,然而函式成員卻只有一份。

當您使用b1.name()方法取回_name的名稱,它會傳回"RBall"名稱,而使用b2.name()時,它會傳回"GBall"名稱,即然類別 的函式成員只有一份,name()如何知道它傳回的_name是b1物件的,還是b2物件的呢?

其實您使用物件名稱來呼叫函式成員時,程式會將物件記憶體位址告知函式成員,而在函式中,一個類別資料成員其實會隱含一個this指標,這個this指標 會儲存傳遞進來的物件指標,當您呼叫name()函式時,其實相當於執行:
string& name() {
    return this->_name;
}

b1呼叫name()方法時,this儲存的就是b1的記憶體位址,而使用b2呼叫name()方法時,this儲存的就是b2的記憶體位址,所以 name()總是可以正確的得知該傳回哪一個物件的_name資料。

每一個類別的函式成員都會隱含一個this指標,用來指向呼叫它的物件,當您在函式中使用資料成員時,都會隱含的使用this指標,當然您也可以明確的指 定,例如在函式定義時使用:
void name(string& name) {
    this-> _name = name;
}

這麼作在這個例子中是多此一舉,只是更明確的在程式碼中撰寫而已,然而這種寫法在某些時機是需要的,例如參數名稱與資料成員名稱相同時,為了識別是參數或 是資料成員,您必須明確的使用this指標來指定,例如:
void name(string& name) {
    this-> name = name; // 假設name是類別成員之一
}