C++中的多重多态性
Multiple polymorphism in C++
下面的测试diamond multiple inheritance
上存在编译错误"‘A’是‘C’的不明确基",
struct A { void f();};
struct B1: A {};
struct B2: A {};
struct C: B1, B2 {};
void g() {A *o = new C;}
它通过下面的virtual inheritance
,来解决
struct B1: virtual A {};
struct B2: virtual A {};
现在,在下面的另一个测试diamond multiple polymorphism
上存在编译错误"对于'C'中的'virtual void A::f()'没有唯一的最终重写器"
struct A {virtual void f();};
struct B1: virtual A {void f();};
struct B2: virtual A {void f();};
struct C: B1, B2 {};
void g() {
A *o = new C;
o->f();
}
即使用下面的dynamic_cast
、也无法解决
dynamic_cast<B1 *>(o)->f();
@注意
dynamic_cast<T *>(obj_ptr)
实际上用于执行typesafe downcast
,即当obj_ptr指向的对象的运行时类型Tobj是T的子类型时,它返回obj_ptr本身;否则为NULL指针。将子类型Tobj上转换为超类型T是错误的,否则在运行时执行上转换直接违背了多态性原则。
IMHO,virtual inheritance
足够简洁,可以在编译时解决前半部分的问题。相比之下,您能在运行时提供任何东西来解决后半部分的问题吗?
@EDIT
谢谢你指出dynamic_cast
不起作用。已更正。
为了解决后半部分的问题,它似乎别无选择,只能在下面的菱形层次结构的最后一个子类上实现overrider
struct C: B1, B2 {
void f() {B1::f();} //Hardcode to your choice of overrider
};
好吧,你仍然没有f()
的唯一覆盖:这需要在C
中使用例如:来定义
struct C: B1, B2 { void f() { this->B1::f(); } };
您可以在不进行动态调度的情况下使用此函数明确限定要强制执行的函数(这是在对象已完全构造且尚未销毁时调用抽象函数的唯一方法)。
即使没有调用,您的第二个示例也是格式错误的。接受它的编译器是非标准一致的。这在C++标准(C++11/10.3.13)中得到了很好的说明:
以下示例显示了一个没有唯一最终否决者:
struct A {
virtual void f();
};
struct VB1 : virtual A { // note virtual derivation
void f();
};
struct VB2 : virtual A {
void f();
};
struct Error : VB1, VB2 { // ill-formed };
struct Okay : VB1, VB2 {
void f();
};
VB1::f和VB2::f都覆盖A::f,但在Error类中没有对这两者进行过度考虑。这个例子是因此形成不良。然而,Class Okay的形式很好,因为好的::f是最后的越权者。
正如您所看到的,还有一个解决方案。在overriden函数中,您可以使用::
来决定要调用哪个父函数,甚至同时调用这两个函数。
struct Okay : VB1, VB2 {
void f() {
VB1::f();
VB2::f();
}
};
f()不明确,因此编译器不知道要调用哪个f()。按照您的建议使用dynamic_cast。
您可能还需要在子类中虚拟量化f()。
struct A {virtual void f();};
struct B1: virtual A {virtual void f();};
struct B2: virtual A {virtual void f();};
struct C: B1, B2 {};
void g() {
A *o = new C;
o->f();
}
- 多态性和功能结合
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- C++boost序列化多态性问题
- 如何查找哪个类对象位于数组的特定索引上(多态性)
- 如何在多线程中正确使用unique_ptr进行多态性?
- 具有智能指针的多态性
- 在 C++ 中在堆栈上创建实例时如何保持多态性?
- 继承/多态性 - 我是否被迫使用"protected"变量?
- C++ 多态性在代码::块 17.12 中不起作用
- C++ 泛型和多态性:这种模式可行吗?
- 为什么我们实际上需要运行时多态性?
- 如何在这个简单的最小示例中实现多态性?
- 如何使用静态多态性在 int 和指针类型之间进行转换?
- 无法初始化已知大小的矢量指针,该大小不会因多态性而更改
- 运行时多态性和dynamic_cast需要澄清
- 如何调用指针类型的方法(禁用多态性)?
- 从基类调用函数的多态性
- 运行时多态性 - 箭头运算符访问了错误的成员?
- 为什么我在虚幻引擎中的多态性和接口方面遇到问题?