use*_*367 16 c++ null member-functions
#include "iostream"
using namespace std;
class A
{
public:
void mprint()
{
cout<<"\n TESTING NULL POINTER";
}
};
int main()
{
A *a = NULL;
a->mprint();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我输出为"TESTING NULL POINTER".任何人都可以解释为什么这个程序打印输出而不是崩溃.我在Dev C++和aCC编译器上检查了它们都给出了相同的结果.
Eri*_*rik 26
您没有使用任何成员变量A- 该函数完全独立于A实例,因此生成的代码恰好不包含任何解除引用0的内容.这仍然是未定义的行为 - 它可能恰好适用于某些编译器.未定义的行为意味着"任何事情都可能发生" - 包括程序恰好像程序员所期望的那样工作.
如果你做mprint虚拟你可能会崩溃 - 或者你可能没有得到一个如果编译器发现它并不真的需要一个vtable.
如果将成员变量添加到A并打印出来,则会发生崩溃.
根据C++规范,此程序具有未定义的行为,因为您在空接收器上调用成员函数.
但是,这种方法的作用是,非虚拟成员函数通常实现为常规函数,将"this"指针作为隐式的第一个参数.因此,如果在空指针上调用成员函数,只要不使用this指针,程序就不会崩溃.当然,你不能依靠这个; 有效的C++编译器可能会导致崩溃.
但是,虚函数是一个不同的故事,因为实际调用的函数需要在运行时解析.这通常涉及对接收器的虚函数表进行内省.因此,如果您尝试在空指针上调用虚拟成员函数,即使te函数不访问它,它仍将导致崩溃.如果你好奇的话,试试吧!
使用指向对象的空指针调用成员函数的结果在c ++中是未定义的行为,因此它可以执行任何操作.
在这种情况下,它可能是因为它重写了你的功能,因为它就像这样
void mprint(A* this);
Run Code Online (Sandbox Code Playgroud)
和你这样的电话
mprint(0);
Run Code Online (Sandbox Code Playgroud)
所以它只是把它称为普通函数,并将空指针作为参数传递给你,你从来没有以任何方式实际使用它.这就解释了为什么它不会崩溃,但编译器可以自由地做任何事情
| 归档时间: |
|
| 查看次数: |
1199 次 |
| 最近记录: |