我知道菱形问题,但问题是 - 当我用谷歌搜索“虚拟继承”时,结果仅提到菱形问题。我想知道它一般是如何工作的,以及它与普通继承有何不同。
我知道当一个类(通常)从另一个类继承时,它只包含它的所有成员(字段和方法,不考虑访问级别)。其中一些可能会被新成员覆盖或隐藏,但它们仍然存在。继承还定义了层次结构中的类之间的某些关系,这会影响转换和多态性。
虚拟继承有何不同?例如:
class A
{
public:
int a;
int b;
void fun(int x)
{}
void gun(int x)
{}
};
class B : public A
{
public:
int a;
int c;
void fun(int x)
{}
void hun(int x)
{}
};
class C : virtual public A
{
public:
int a;
int c;
void fun(int x)
{}
void hun(int x)
{}
};
B
和 C
有什么区别?还有我的示例没有利用的任何其他差异吗?标准怎么说?此外,如果 C++03 和 C++11 之间存在差异,请指出。
最佳答案
通过单一继承级别,行为没有区别。
区别在于从多个基类继承时,它们本身有一个共同的基类:
struct A {};
struct B : virtual A {};
struct C : virtual A {};
struct D : B,C {};
在这个例子中,通过虚拟继承,D
只包含一个 A
子对象,它的 B
和 C
子对象共享;这是“菱形”图案:
A
/ \
B C
\ /
D
如果没有虚拟继承,它将包含两个 A
子对象,并且没有“钻石”:
A A
| |
B C
\ /
D
有或没有多重继承,如果你有不止一层的继承,还是有区别的:虚基类必须由最派生的类初始化,而不是由它的直接派生类初始化。这是为了避免在多重继承的情况下出现歧义,其中(在上面的示例中)B
和 C
否则将负责初始化共享的 A
。
关于c++ - 虚拟继承实际上是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26509757/