返回信息流如下代码。面试的时候问到的,自己运行了,但是没太弄清背后的原理。
class B {
public:
void p() { cout << "p()" << endl; };
virtual void vp() { cout << "vp()" << endl; };
};
int main()
{
((B*) nullptr)->p();
((B*) nullptr)->vp();
}
这是一条镜像帖。来源:北邮人论坛 / cpp / #101891同步于 2022/4/29
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
求分析一下这两个空指针强转背后的原理
a13261759922
2022/4/29镜像同步4 回复
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
其实都是UB 调用对象方法应该是thiscall
具体到题目来说,非虚函数调用会在编译时确定函数的地址,所以p()会被调用;虚函数会在运行时根据对象的虚表决定调用函数的地址,但空指针显然没有虚表,所以vp()不会被调用
感谢指点,刚查了查thiscall的概念,明白为啥空指针可以直接调用函数了
【 在 specops 的大作中提到: 】
: 其实都是UB 调用对象方法应该是thiscall
: 具体到题目来说,非虚函数调用会在编译时确定函数的地址,所以p()会被调用;虚函数会在运行时根据对象的虚表决定调用函数的地址,但空指针显然没有虚表,所以vp()不会被调用
对的,不过类的成员函数的代码并不存放于类中,而是独立存放,在调用的时候通过在参数列表中传入 this 指针来访问对应的类成员变量
p()函数拿到的this参数虽然为nullptr,但是由于它没有使用到this指针,所以本次调用不会有问题
vp()本身也不会有问题,但它是虚函数,它的地址需要访问类B的虚表获得,而此时类指针为nullptr,因此虚表也为nullptr,访问虚表时会出现 Segmentation fault
【 在 sworduo 的大作中提到: 】
: 我的理解是指针强转为B,就是以B的格式来解释这一块内存