可能重复:
为什么我能够使用无效的类指针进行函数调用
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)
这是NULL(或无效的)对象指针的旧故事; 对于标准,在NULL对象指针上调用方法会导致未定义的行为,这意味着,就标准而言,它可以完美地工作,它可能会炸毁计算机或杀死一些随机的人.
这里发生的是C++编译器典型的类实现的结果:类通常实际上只包含字段的结构,所有方法实际上都是将this指针作为隐藏参数的函数.
现在,在这种实现中,如果你用一个NULL this指针调用一个方法,如果它不访问任何字段,它实际上不会取消引用this,所以它应该运行正常(如同func1).
相反,如果该方法试图访问任何字段(例如func2),它将取消引用this指针,这NULL将导致崩溃(取消引用NULL它的指针,再次,未定义的行为,但通常会导致崩溃).
请注意,如果您调用的方法是虚拟的,那么几乎可以肯定用NULL this指针调用它们会导致崩溃,因为虚拟调用是通过vtable(一个函数指针数组)解决的,该函数在开头隐藏班级.
顺便说一句,void main()不标准; 它应该是int main()(argv而且argc是可选的).
当代码被修复为编译时,结果是合理预期的.
的func1()未引用类的任何成员,因此它不会发现它有一个空指针与作为工作this; func2()确实是引用this->i,因此当this为null 时失败.
严格来说,它是未定义的行为 - 任何事情都可能发生.但核心转储或运行时异常是对该特定错误的最常见响应之一.