当我调用NULL对象指针的成员函数时会发生什么?
我作为一个采访问题被给予以下:
class A { public: void fun() { std::cout << "fun" << std::endl; } }; A* a = NULL; a->fun();
这段代码执行后会发生什么,为什么?
也可以看看:
- 什么时候调用null实例的成员函数会导致未定义的行为?
这是未定义的行为,所以可能发生任何事情。
一个可能的结果是,它只是打印"fun"
因为该方法不访问它被调用的对象的任何成员variables(对象据认为居住的内存不需要被访问,所以访问冲突“一定会发生)。
按照标准,这是不确定的行为,因此是一件非常糟糕的事情。 在大多数编程平台(跨X86和其他几种架构)的实际情况下,这样可以很好地运行。
为什么? 考虑如何在C ++中实现类的function。 这不是一个虚拟函数,因此这可以是对已知地址的静态调用。 在x86汇编中,我们可以看到这个
mov A, 0 mov ecx, A call a__fun
因为a__fun不需要实例数据,即使它接收到null指针,也不会发生任何事情。
仍然低劣的代码和任何编译器会尖叫,但它可以运行。
在大多数现代计算机上,最可能的行为是运行,并打印出“有趣的”,因为:
- 在调用函数之前,C ++不检查指针是否为NULL
-
fun()
不是虚拟的,所以不需要引用一个vtable来调用fun()
-
fun()
永远不会访问A
任何成员variables,所以它不需要将this
指针的空值解引用。
我们不知道会发生什么。 一切都可能发生,因为程序暴露了未定义的行为。 请参阅在空实例上调用成员函数是否导致未定义的行为? 。
我多次尝试过,一直输出“快乐”,这是因为函数fun
独立于实例a
。 同时调用a->fun();
指向0,所以这是未定义的行为,但在大多数编译器应该没有崩溃。