關於C++中指向類的指針

事情緣起是因爲上班途中刷到了有個微博,那人說答對這個問題的請發簡歷。

看了就是關於指向C++類的指針的知識,原代碼類似下面這樣:

class NullPointCall
{
public:
    void display()
    {
        std::cout << "It's nice!" << std::endl;
    };

private:
    int m_nNum;
};

問題類似於:

NullPointCall *pNull = NULL;
pNull->display();  
// 求問結果是什麼  
// A、coredump
// B、顯示It is nice!
// C、...(我忘了啥答案了  囧...)
// D、其他錯誤

然後參考了網上的博客,這有關this指針。

class NullPointCall
{
public:
    static void Test1()
    {
        std::cout << m_nStaticInt << std::endl;
    };

    void Test2()
    {
        std::cout << "It is nice!" << std::endl;
    };

    void Test3(int nInputNum)
    {
        std::cout << nInputNum << std::endl;
    };

    void Test4()
    {
        std::cout << m_nVariable << std::endl;
    };

private:
    static int m_nStaticInt;
    int m_nVariable;
};

int NullPointCall::m_staticInt = -10;

然後測試如下:

NullPointCall *pNull = NULL;
pNull->Test1();
pNull->Test2();
pNull->Test3(2);
pNull->Test4();

然後輸出爲:

-10
It is nice!
2
Test4()失敗,內存訪問衝突

對於類成員函數而言,並不是一個對象對應一個單獨的成員函數體,而是此類的所有對象共用這個成員函數體。 當程序被編譯之後,此成員函數地址即已確定。而成員函數之所以能把屬於此類的各個對象的數據區別開, 就是靠這個this指針。函數體內所有對類數據成員的訪問, 都會被轉化爲this->數據成員的方式。

當在類的非靜態成員函數中訪問類的非靜態成員的時候,編譯器會自動將對象本身的地址作爲一個隱含參數傳遞給函數。即使你沒有寫上this指針,編譯器在編譯的時候也是加上this的。

對於上面的例子來說,this的值也就是pNull的值。也就是說this的值爲NULL。
Test1()是靜態函數,編譯器不會給它傳遞this指針,所以call 1那行代碼可以正確調用(這裏相當於NullPointCall::Test1())。
對於Test2()和Test3()兩個成員函數,雖然編譯器會給這兩個函數傳遞this指針,但是它們並沒有通過this指針來訪問類的成員變量,所以Test2()和Test3()兩行代碼可以正確調用。
而對於成員函數Test4()要訪問類的成員變量,因此要使用this指針:

void NullPointCall::Test4(NullPointCall *this)
{
    std::cout << this->m_nVariable << std::endl; 
}

相當於:

void NullPointCall::Test4(NULL)
{
    std::cout << this->m_nVariable << std::endl; 
}

這個時候發現this指針的值爲NULL,就會造成程序的崩潰。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章