c++中具有多重继承的强制转换
Casting with multiple inheritance in C++
下面的代码不能编译,gcc -std=c++11
说这是一个无效的静态强制转换:
class A { public: virtual ~A() {} };
class B { public: virtual ~B() {} };
class AD : public A { public: virtual ~AD() {} };
class AB : public B, public A {};
class ADB : public B, public AD {};
int main() {
ADB adb;
ADB* ptr = &adb;
AB* cast = static_cast<AB*>(ptr);
return 0;
}
我想将类型为ADB
的类强制转换为AB
。这个感觉应该是安全的——毕竟,ADB
的内存结构是B
后面跟着AD
,而CC_6本身就是A
后面跟着AD
自己的成员。因此,强制编译器将指针ptr
解释为AB
似乎总是定义为:
class A { public: virtual ~A() {} };
class B { public: virtual ~B() {} };
class AD : public A { public: virtual ~AD() {} };
class AB : public B, public A {};
class ADB : public B, public AD {};
int main() {
ADB adb;
ADB* ptr = &adb;
AB* cast = reinterpret_cast<AB*>(ptr);
return 0;
}
这也不会编译,导致链接器抱怨未定义的引用
所以很明显,在某种程度上,虚函数表指针在强制转换时没有"同步",在这种情况下,我需要将ADB
的AD
的单个基类强制转换为AB
的A
。我不是很确定,只是猜测。我该怎么做呢?
只能在对象继承结构中的类之间成功强制转换。因此,您可以将ADB转换为A、B或AD。你对类似内存布局的合理化并不适用。虽然对底层实现的理解可以对某些"如何"answers"为什么"提供有用的见解(特别是当涉及到性能时),但您不应该必须考虑底层实现来理解(或合理化)语言特性的规则。它的工作方式是帮助你表达更高层次的意图。
更重要的是,您永远不应该基于底层实现的知识来规避语言内置的限制。虽然偶尔可以这样做,但大多数情况下,它将导致不可移植的代码或无法在编译器更新后存活的代码-无法编译或在生产中神秘地中断。
无论如何,你关于内存布局的假设可能是不正确的;定义虚析构函数会迫使编译器将虚函数表指针注入到A、B和AD的内存布局中,因此ADB的实际内存布局可能不是您想象的那样。
如果要强制转换AB
,则静态强制转换只能将AB
强制转换为B
或A
。就是这样。
这是在编译时提供static_cast
的保证:它只允许在相关类型之间逻辑 ok的强制转换操作。
您也可以想象这些static_cast,它们将是正确的:
- 和AD 中的A
- AB中的B或a
- ADB中的B或AD
- 和ADB 中的A
但是在AB和ADB之间的继承层次结构中没有路径来做你想做的事情。AB和ADB绝对不是相关的类型。
- 关于C++中具有多重继承"this"指针的说明
- C++中模板化异常类的多重继承
- 虚拟继承中是否存在多重继承?
- 如何在 c++ 多重继承中调用父非虚函数?
- C++ MSVC 中的访问冲突,但不在 GCC 中进行多重继承和强制转换
- 在多重继承场景中动态强制转换类型
- 将void*强制转换为具有多重继承的类
- 多重继承强制转换未按预期工作
- c++多重继承强制转换是如何工作的
- C++ 从接口和强制转换的多重继承
- 虚拟多重继承和强制转换
- 强制转换为多重继承
- C++ 中的多重继承转换
- 多重继承c++,如何进行类型转换
- c++中具有多重继承的强制转换
- 多重继承和强制类型转换
- 当使用多重继承时,静态强制转换是安全的
- 从基类到不同派生类的多重继承强制转换
- 将我的c++代码转换为Java:转换多重继承
- 如何使用多重继承执行强制转换