有趣的C++代码片段,有什么解释吗?

Alo*_*ave 0 c++ null

可能重复:
为什么我能够使用无效的类指针进行函数调用

class B
{
    public:
    int i;
    B():i(0){}
    void func1()
    {
        cout<<“func1::B\n”;
    }
    void func2()
    {
        cout<<“i = “<<i;
    } 
};


int main()
{

    B *bp = new B;

    bp->func1();

    delete bp;

    bp = NULL;

    bp->func1();
    bp->func2();

    return 1; 
}
Run Code Online (Sandbox Code Playgroud)

输出:

func1::B 
func1::B 
Runtime Exception:
NULL pointer access
Run Code Online (Sandbox Code Playgroud)

Mat*_*lia 7

这是NULL(或无效的)对象指针的旧故事; 对于标准,在NULL对象指针上调用方法会导致未定义的行为,这意味着,就标准而言,它可以完美地工作,它可能会炸毁计算机或杀死一些随机的人.

这里发生的是C++编译器典型的类实现的结果:类通常实际上只包含字段的结构,所有方法实际上都是将this指针作为隐藏参数的函数.

现在,在这种实现中,如果你用一个NULL this指针调用一个方法,如果它不访问任何字段,它实际上不会取消引用this,所以它应该运行正常(如同func1).

相反,如果该方法试图访问任何字段(例如func2),它将取消引用this指针,这NULL将导致崩溃(取消引用NULL它的指针,再次,未定义的行为,但通常会导致崩溃).

请注意,如果您调用的方法是虚拟的,那么几乎可以肯定用NULL this指针调用它们会导致崩溃,因为虚拟调用是通过vtable(一个函数指针数组)解决的,该函数在开头隐藏班级.

顺便说一句,void main()不标准; 它应该是int main()(argv而且argc是可选的).


Jon*_*ler 5

当代码被修复为编译时,结果是合理预期的.

func1()未引用类的任何成员,因此它不会发现它有一个空指针与作为工作this; func2()确实是引用this->i,因此当this为null 时失败.

严格来说,它是未定义的行为 - 任何事情都可能发生.但核心转储或运行时异常是对该特定错误的最常见响应之一.