C++中使用reinterpret_cast转换非虚基类引用为虚基类引用是否合法?
关于C++中reinterpret_cast跨基类转换的合法性分析
这段代码里的reinterpret_cast转换属于C++标准定义的未定义行为,具体细节如下:
reinterpret_cast的合法边界
C++标准对reinterpret_cast的引用转换有严格限制:仅允许同类型引用之间转换,或者转换为char/unsigned char/std::byte类型的引用(用于访问对象原始字节),以及少数特定的函数指针/引用转换场景。直接将一个基类的引用强制转换为另一个无继承关系的基类引用,完全不在合法范围内。不同编译器表现差异的本质
GCC和Clang能运行只是巧合:由于implementer是空类,这两个编译器的内存布局优化可能让implementer子对象的地址与poly对象起始地址重合,而base作为带虚函数的基类,其地址也恰好与poly起始地址一致,导致转换后的引用刚好能正确访问base的虚表。但这是编译器的特定实现细节,不具备可移植性——一旦调整类定义(比如给implementer添加成员变量),或者换用MSVC这类内存布局规则不同的编译器,就会出现内存访问错误。类型擦除的正确做法
如果要实现从implementer引用获取base接口的类型擦除,必须通过类型安全的方式:
- 在
implementer中定义虚函数,让派生类poly重写它以返回自身的base指针/引用; - 在类型擦除的包装逻辑中,直接持有
base类型的指针/引用,避免跨基类的强制转换; - 绝对不能依赖
reinterpret_cast这种未定义行为来实现类型转换。
内容的提问来源于stack exchange,提问作者Fantastic Mr Fox
相关产品推荐
相关产品推荐

