2016-03-03 200 views
4

我不明白下面的代碼片段如何生成給定的輸出。將指針設置爲空後通過指針訪問函數

#include <iostream> 
using namespace std; 

class MyClass 
{ 
    public: 
    void doSomething() 
    { 
     cout<<"Inside doSomething"<<endl; 
    } 
}; 

int main() 
{ 
    MyClass obj; 
    MyClass *ptr=&obj; 
    ptr->doSomething(); 
    ptr=NULL; 
    ptr->doSomething(); 
} 

輸出


內DoSomething的
內DoSomething的

我執行的功能與一個空指針,它實際上調用該函數。 使用ptr的ptr檢索存儲在ptr中的地址表明在語句ptr = NULL之後ptr被設置爲0;但它仍然會調用doSomething()。實際內部發生了什麼?

回答

9

這是Undefined Behaviour,絕對會發生任何事情,包括出現工作。 這是不可靠的!

在這種情況下,它不會崩潰,只是因爲MyClass::doSomething()功能不會做其this指針任何東西(這將是NULL,所以容易導致崩潰)。

如果你給MyClass成員,並試圖訪問在doSomething(),我希望看到一個crash (segfault)

class MyClass 
{ 
    int someNum; 
    public: 
    void doSomething() 
    { 
     cout<< "Inside doSomething: " << this->someNum <<endl; 
    } 
}; 

(在我用gcc 4.9.2測試在Linux上,我。確實看到了段錯誤。)


此外,請重新考慮你的陋習using namespace std;endl使用。

2

原因是你只能訪問總是存在的類的代碼段。

但是,當您嘗試從函數中訪問任何成員變量時,您很可能會崩潰。

因此,隱藏這個指針爲每個函數傳遞,所以在刪除對象後,這個指針是無效的。所以對這個指針的任何訪問都會在對象被刪除後崩潰。

這裏被簡化內部的動作的版本:

doSomething(MyClass * this) 
{ 
    // Will work OK if 'this' pointer is NULL, but NOT used. 

    // Will Crash if 'this' pointer is used. 
    this->data = 100; 
}