【发布时间】:2013-09-18 05:44:51
【问题描述】:
有什么区别
class A {};
class Z: public A {};
和
class A {};
class Z: virtual public A {};
【问题讨论】:
-
你可以看看“钻石问题”。见this question。
标签: c++ inheritance virtual
有什么区别
class A {};
class Z: public A {};
和
class A {};
class Z: virtual public A {};
【问题讨论】:
标签: c++ inheritance virtual
假设没有额外的继承层次结构,这种情况下没有区别。唯一能看出区别的方法是通过多种方式继承同一个类——例如,如下:
class ZA : public Z, public A {};
对比
class ZA : virtual public Z, virtual public A {};
在第一种情况下,ZA 将有两个具有独立 As 的区域 - 一个直接继承,一个通过 Z 继承。在第二种情况下,将只有一个A,通过两条路径继承并共享。
这是一个例子:
【讨论】:
Assuming that there is no additional inheritance hierarchy, there is no difference in this case. 这不是真的。在第一种情况下,sizeof(Z) 通常是一个。但在第二种情况下,sizeof(Z) 通常是sizeof(void*),因为即使A 和Z 不包含虚成员函数,Z 也会包含一个 vtable 指针。
不同之处在于当您从共享公共基类的多个类继承时的行为:
class A {};
class Y : public A {};
class Z : public A {};
class YZ: public Y, public Z {};
在这种情况下,使用非虚拟继承,YZ 对象将包含 Y 和 Z 子对象,每个子对象都有自己的 A 子对象。
这通常不是您想要的,因为它不遵循继承通常建模的“is-a”关系:有两种不同的方式可以将YZ 视为A。
void f(A&);
YZ yz;
f(yz); // ERROR: which A?
但是对于A的虚拟继承,将只有一个A子对象,由Y和Z共享;上面的例子现在是明确的。
【讨论】:
假设您有两个派生类B 和C,它们有一个公共基类A。你还有另一个类D 继承了它们。您将使用public virtual A 来确保B 和C 使用相同的子对象A。
信息取自这里:Virtual Base Classes
【讨论】: