不报错调用空指针类的成员函数

究竟什么原因使得空指针实例调用成员函数也能正常运行?

  猜猜下列例子运行会有什么结果?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class A
{
public:
static void print()
{
printf(">>>>>\n");
}

void print2()
{
printf("+++++\n");
}

void print3()
{
printf("====%d\n", value);
}

private:
int value;
};

int main(int argc, char *argv[])
{
A *a = NULL;
a->print();
a->print2();
a->print3();
return 0;
}

  运行结果:

1
2
3
a->print()  输出:>>>>>
a->print2() 输出:+++++
a->print3() 程序段错误

  前两个应该都会段错误才对的呀,怎么都运行正常了。其实上述的行为都由this指针左右结果。

0x00 静态函数没有this指针

  静态方法随着类的加载而加载,静态方法不需要实例化。不会引用到this指针里面的数据,所以static void print()不会报错。

0x01 成员函数不使用this指针不报错

  a->print();可以近似看作void print(A *a)调用,展开是这样:

1
2
3
4
void print(A *a)
{
printf("+++++\n");
}

  由此A的实例a指针没有被使用,不会访问到错误的地址而出现异常。

0x02 空指针引用实例成员才会异常

  void print3()中使用了实例a的value成员,由于a为空,没有指向具体的内存,导致引用value内存出错。

0x03 总结

  上述行为引起段错误的原因是空指针实例引用了成员变量导致的。


更多精彩文章请关注微信公众号:「Qt君」