#include <iostream>
using namespace std;
class test
{
int i;
public:
test():i(0){ cout << "ctor called" << endl;}
void show()
{
cout<<"show fun called"<<endl;
}
};
int main(int argc , char *argv[])
{
test *ptr = NULL;
ptr->show();
return 0;
}
显然,不会打电话给ctor。这是标准吗?或者只是一些编译器优化,因为这个指针没有在show()成员函数中使用?
答案 0 :(得分:24)
调用该方法不需要指针。指针的类型是已知的,因此该方法的代码是已知的。该方法不使用this
,因此它运行代码就好了。它是未定义的行为,但更有效的是不检查指针是否为NULL,因此它运行。
答案 1 :(得分:10)
如果你看一下程序集(对于至少一个编译器),你可以看到它运行的原因(即使它是未定义的行为,正如许多人所指出的那样)。对于这两行:
test *ptr = NULL;
ptr->show();
生成此程序集(在我刚试过的一个编译器中):
00000004: C7 45 FC 00 00 00 mov dword ptr [ebp-4],0
00
0000000B: 8B 4D FC mov ecx,dword ptr [ebp-4]
0000000E: E8 00 00 00 00 call ?show@test@@QAEXXZ
它推送堆栈上的NULL(0)并调用该方法,因为该方法的地址独立于实际的对象实例。
答案 2 :(得分:1)
它无效,行为未定义,实际结果取决于您的编译器。
答案 3 :(得分:0)
嗯,首先,它无效,因为它会调用未定义的行为。你真的在问为什么编译器允许它,答案是因为这是一个根本不会在真实应用程序中出现的骨头代码,为什么要这么麻烦?当指针在运行时无效时,真正的问题就出现了静态代码分析无法预料的方式。
编译器无法抓住您的手,它可以根据标准编译您的代码。如果它提供有用的警告那么好,但在那里没有任何语法或语义上的非法,你只是编写导致未定义行为的代码。