C++ this指針詳解


this指針:
每個成員函數都有一個隱含的輸入參數this指針,this指向當前對象,this指針可以用來訪問對象的數據成員。
class B {
public:
       void fun1() {
       }
       void fun() const{
             printf("成員函數地址:%x\n", &B::fun1);
             printf("成員數據x的地址:%x\n", &x);
             printf("成員數據y的地址:%x\n", &y);
             printf("當前對象地址:%x\n", this);
             printf("當前對象的this指針類型:%s\n", typeid(this).name());
             printf("\n");
       }
       int x;
       int y;
};
int main() {
       B b1, b2;
       const B b3;
       b1.fun();
       b2.fun();
       b3.fun();
}

 結果:

成員函數地址:f8114f
成員數據x的地址:cffd94
成員數據y的地址:cffd98
當前對象地址:cffd94
當前對象的this指針類型:class B const *
 
成員函數地址:f8114f
成員數據x的地址:cffd84
成員數據y的地址:cffd88
當前對象地址:cffd84
當前對象的this指針類型:class B const *
 
成員函數地址:f8114f
成員數據x的地址:cffd74
成員數據y的地址:cffd78
當前對象地址:cffd74
當前對象的this指針類型:class B const *

 

 
結論:成員函數是屬於類的,成員數據是屬於對象的。
 
 
 
程序修改成:
 
class B {
public:
       void fun1() {
       }
       void fun() const{
             printf("成員函數地址:%x\n", &B::fun1);
             printf("成員數據x的地址:%x\n", &x);
             printf("成員數據y的地址:%x\n", &y);
             printf("當前對象地址:%x\n", this);
             printf("當前對象的this指針類型:%s\n", typeid(this).name());
             printf("\n");
       }
       void fun() {
             printf("成員函數地址:%x\n", &B::fun1);
             printf("成員數據x的地址:%x\n", &x);
             printf("成員數據y的地址:%x\n", &y);
             printf("當前對象地址:%x\n", this);
             printf("當前對象的this指針類型:%s\n", typeid(this).name());
             printf("\n");
       }
       int x;
       int y;
};
int main() {
       B b1, b2;
       const B b3;
       b1.fun();
       b2.fun();
       b3.fun();
}

 結果:

成員函數地址:931ac8
成員數據x的地址:12ffbb4
成員數據y的地址:12ffbb8
當前對象地址:12ffbb4
當前對象的this指針類型:class B *
 
成員函數地址:931ac8
成員數據x的地址:12ffba4
成員數據y的地址:12ffba8
當前對象地址:12ffba4
當前對象的this指針類型:class B *
 
成員函數地址:931ac8
成員數據x的地址:12ffb94
成員數據y的地址:12ffb98
當前對象地址:12ffb94
當前對象的this指針類型:class B const *

 

 結論:當前this指針的類型不僅與對象(const or not)有關,還與對象所調用的成員函數有關。
 
那么,為什么可以用this指針訪問成員函數呢?
class B {
public:
    void fun1() {
        printf("fun1()\n");
    }
    void fun2() {
        this->fun1();
    }
};

 猜測:每個對象都需要訪問成員函數,那么,該對象里一定復制了類的成員函數(應該放在內存的程序段)的地址;既然對象與類有關,那么對象里除了數據成員之外,肯還有其他與類相關的信息。

還有一種可能是,類的成員函數在編譯時都修飾成類名有關的名稱,這個名稱變成了全局唯一的函數名,這些函數都應該放在內存的代碼段位置;當對象訪問成員函數時,將直接使用修飾過后的名稱來調用;而非類的對象調用類的成員函數時,無法使用修飾過的函數名,所以訪問出錯。這樣看來,通過this指針訪問成員函數,與直接訪問成員函數沒有區別,或者說this指針與成員函數沒有關系。之所以允許這種寫法,是為了讓人看上去更直觀一些。

 

static成員函數與this指針:

static成員函數沒有默認將this指針參數,所以static成員無法訪問對象的數據,只能訪問static數據成員。 

 

為什么說this指針不是對象的一部分?this指針所占用的內存不會反應在sizeof的結果中?

this指針是動態構造的,只有在調用非靜態成員函數時,才臨時構造並傳入到成員函數的形參中,調用完畢則被銷毀(與形參的屬性一致),猜測這就是平時並不占用對象的內存的原因。

 

虛函數中的this指針:

在虛函數所在類中,有一張虛函數表,而類的對象則有一個虛表指針,指向這張虛表。當虛函數被子類的函數覆蓋(重寫)時,虛函數表中的相應位置的函數指針將被替換成子類的函數指針。this指針相當於虛表指針?

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM