2021-03-08 C++利用类静态变量,实现伪类对象空指针成功访问含有成员变量的成员函数而不崩溃

本文探讨了C++中空指针调用成员函数的现象及其背后的原理。虽然空指针可以调用非虚成员函数,但由于this指针为空,如果函数内涉及this指针的操作会导致程序崩溃。而对于虚函数,由于其涉及到虚函数表,空指针无法提供正确的对象地址,因此调用虚函数会出错。理解this指针和虚函数表在内存中的作用是避免这类问题的关键。
摘要由CSDN通过智能技术生成

现象: 空指针调用成员函数(不含普通成员变量),是没有问题的,但是调用它的虚函数就会出错。当然,在两种情况在编译时都能通过。
原因:
问题一:空指针为什么能调用成员函数?
对于类成员函数而言,并不是一个对象对应一个单独的成员函数体,而是此类的所有对象共用这个成员函数体。 当程序被编译之后,此成员函数地址即已确定。当调用p->func1(); 这句话时,其实就是调用A::func1(this);而成员函数的地址在编译时就已经确定, 需要注意的是,你用空指针调用成员函数,只是让this指针指向了空,所以空指针也是可以调用普通成员函数,只不过此时的this指针指向空而已,但函数fun1函数体内并没有用到this指针,所以不会出现问题。当成员函数体内用到this指针时,如果你的this指针是空,那么程序就会崩溃。比如,如果把**_a=1; ** 这句话放开,程序就会出问题,原因就是this指针指向空,当进行赋值的时候,编译器不知道这个成员变量是哪一个对象的,所以他不知道给哪个对象的_a赋值,因此就会出错。

问题二:空指针为什么不能调用虚函数?
我们知道,如果一个类中包含虚函数,那么他所实例化处的对象的前四个字节是一个虚表指针,这个虚表指针指向的是虚函数表。当然,虚函数的地址也是在编译时就已经确定了,这些虚函数地址存放在虚函数表里面,而虚函数表就在程序地址空间的数据段(静态区),也就是说虚表的建立是在编译阶段就完成的;当调用构造函数的时候才会初始化虚函数表指针,即把虚表指针存放在对象前四个字节(32位下)。试想一下,假如用空指针调用虚函数,这个指针根本就找不到对应的对象的地址,因此他也不知道虚表的地址,没有虚表的地址,怎么能调用虚函数呢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值