假设我们有通常的菱形图案:
class A
{
public:
virtual char foo() = 0;
virtual ~A() {}
};
class B : public A
{
public:
virtual char foo() { return 'B';}
virtual ~B() {}
};
class C : public A
{
public:
virtual char foo() { return 'C';}
virtual ~C() {}
};
class D : public B, public C
{
public:
virtual char foo() { return 'D';}
virtual ~D() {}
};
请注意基类 A
没有任何数据成员。它实际上只是一个带有纯虚方法的接口(interface)。
现在如果我这样做:
D* d = new D();
A* a = static_cast<A*>(d);
编译器会告诉我转换不明确,因为有两个 A 基类。
但是如果我这样做呢:
D* d = new D();
B* b = static_cast<B*>(d); // Or C* c = static_cast<C*>(d);
A* a = static_cast<A*>(b);
现在我有一个指向我的 A
基类之一的指针,我可以执行 a->foo()
。
这样安全吗?
我想知道的是,我是否可以进行这种双重向上转换以仅具有指向接口(interface)的指针(没有数据成员)而没有虚拟继承的开销。我不打算向下转换指针或对它做任何不调用虚拟方法的事情。
我知道这意味着有两个基类,但由于没有成员,所以应该无关紧要,是吗?
编辑
:
我正在努力寻找一种实现接口(interface)的方法,我想我只需要使用虚拟继承。
假设我有一个 Buffer
类(接口(interface)类)和一个派生自它的 BufferImplementation
类。
现在假设我有另一个接口(interface) IOBuffer
(它派生自另一个接口(interface) Buffer
),其中有一个 IOBufferImplementation
类必须派生自BufferImplementation
和 IOBuffer
接口(interface)。
在我之前的例子中,Buffer是A,BufferImplementation是B,IOBuffer是C,IOBufferImplementation是D。
最佳答案
Is this safe?
我是这么认为的。您正在使用两条路径之一从派生类 D
到达基类 A
。您现在可以安全地使用接口(interface)成员。
请注意,如果 A
中的纯虚方法 未在 D
中被覆盖
,然后使用 D->B->A
路径将始终调用 B
中的 overridden
方法(类似于 D->C->A
路径),尽管 C
中的实现是有意/有用的。当 A
具有数据成员时,这也将起作用,并且在此特定设置中,将使用通过 D->B->A
继承的数据成员。
关于c++ - 没有数据成员的菱形(多重继承),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23580585/