2016-03-03 144 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; 
}