NPS*_*NPS 1 c++ inheritance virtual-inheritance
我知道钻石问题,但问题是 - 当我谷歌"虚拟继承"时,结果只提到钻石问题.我想知道它一般是如何工作的,它与正常继承有什么不同.
我知道当一个类(通常)继承自另一个类时,它只包含其所有成员(字段和方法,不考虑访问级别).其中一些可能会被新成员覆盖或隐藏,但他们仍然存在.继承还定义了层次结构中类之间的某些关系,这些关系会影响转换和多态.
现在虚拟继承有何不同?例如:
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)
{}
};
Run Code Online (Sandbox Code Playgroud)
B和之间有什么区别C?我的例子没有利用其他任何差异吗?标准说什么?另外,如果C++ 03和C++ 11之间存在差异,请提及它.
使用单一级别的继承,行为没有区别.
不同之处在于从多个基类继承时,这些基类本身具有公共基类:
struct A {};
struct B : virtual A {};
struct C : virtual A {};
struct D : B,C {};
Run Code Online (Sandbox Code Playgroud)
在这个例子中,使用虚拟继承,D只包含一个A子对象,它B和C子对象共享; 这是"钻石"模式:
A
/ \
B C
\ /
D
Run Code Online (Sandbox Code Playgroud)
没有虚拟继承,它将包含两个A子对象,而不是"菱形":
A A
| |
B C
\ /
D
Run Code Online (Sandbox Code Playgroud)
无论是否有多重继承,如果您有多个继承级别,仍然存在差异:虚拟基类必须由派生类最多的类初始化,而不是由其直接派生类初始化.这是为了避免在多重继承的情况下,歧义其中(在上面的例子中)都B与C原本负责初始化共享A.