为什么在C++中通过空指针调用方法"工作"?

bbc*_*bbc 8 c++

可能重复:
通过NULL类指针调用类方法

#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;
}
Run Code Online (Sandbox Code Playgroud)

很明显,没有人会被召唤.这是标准吗?或者只是一些编译器优化,因为这个指针没有在show()成员函数中使用?

Ned*_*der 26

调用该方法不需要指针.指针的类型是已知的,因此该方法的代码是已知的.该方法不使用this,因此它运行代码就好了.它是未定义的行为,但更有效的是不检查指针是否为NULL,因此它运行.

  • 我希望虚方法调用失败,因为它需要查找vtable中的方法,它会在指针的另一端找到,但指针是NULL. (3认同)
  • (如何)虚拟方法会影响他观察到的行为? (2认同)

Mar*_*ins 10

如果你看一下程序集(对于至少一个编译器),你可以看到它运行的原因(即使它是未定义的行为,正如许多人所指出的那样).对于这两行:

test *ptr = NULL;
ptr->show();
Run Code Online (Sandbox Code Playgroud)

生成此程序集(在我刚试过的一个编译器中):

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
Run Code Online (Sandbox Code Playgroud)

它会推送堆栈上的NULL(0)并调用该方法,因为该方法的地址独立于实际的对象实例.