You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中通过错误指针调用基类成员函数的合法性及虚拟场景影响

C++代码合法性分析(仅语言规则层面)

原代码

struct Base {
  int f() { return 42; }
};
struct D1 : Base {};
struct D2 : Base {};

int main() {
  D2 d2;
  D1* ouch = reinterpret_cast<D1*>(&d2);
  return ouch->f();
}

原代码合法性判断

这段代码是合法的。核心依据如下:

  • 非虚成员函数Base::f()的调用地址在编译阶段就已确定,不依赖运行时对象的实际类型。
  • ouch->f()本质是将D1*类型的ouch隐式转换为Base*,作为this指针传递给Base::f()。
  • D1和D2都是Base的非虚单继承派生类,其内存布局中Base子对象位于派生类对象起始位置。reinterpret_cast得到的ouch指向D2对象的起始地址,转换为Base*后恰好指向D2中有效的Base子对象,满足非静态成员函数对this指针的有效性要求。

变体情况分析

1. 当f()为虚函数时

此时代码属于未定义行为。
虚函数调用依赖对象的虚表指针:D2对象的虚表指针指向D2的类虚表,而通过reinterpret_cast得到的D1*指针调用虚函数时,编译器会按照D1的内存布局访问虚表。C++标准未保证不同派生类的虚表布局或虚表指针位置一致,这种跨类型的虚函数调用违反类型安全,行为完全不可预期。

2. 当继承为虚继承时

无论f()是否为虚函数,代码均属于未定义行为。
虚继承下,Base子对象在派生类中的位置由编译器自由决定,不再固定在起始位置。D1和D2的Base子对象位置可能不同,reinterpret_cast<D1*>(&d2)转换后的指针,在隐式转为Base*时无法正确指向D2中的Base子对象,导致this指针无效,触发未定义行为。


内容的提问来源于stack exchange,提问作者dtldarek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 07:36:32