虚拟和内联是函数说明符。
它们只能出现在功能之前。{根据我的理解}。
然后,在下面的代码中什么是虚拟的?
class Base
{
//
};
class Derived :virtual public Base
{
};
答案 0 :(得分:5)
答案 1 :(得分:2)
$ 10.1 / 4-“基类说明符 包含关键字virtual, 指定虚拟基类。对于 每个不同的发生 类中的非虚基类 最派生类的格子, 大多数派生对象(1.8)应 包含相应的不同基础 该类的子对象。 每个人 指定的不同基类 虚拟的,最派生的对象应该 包含单个基类子对象 那种类型。“
所以给出了层次结构
struct A{};
struct B : virtual A{};
struct C : virtual A{};
struct D : B, C{};
D d;
'd'对象只有一个'A'子对象,即'A'的构造函数只被调用一次,并且在任何其他构造函数运行之前也是如此。
$ 12.6.2 / 5 - “初始化应 按以下顺序进行:
- 首先,仅适用于构造函数 如上所述的派生类最多 下面,虚拟基类应该是 按照它们出现的顺序初始化 在深度优先从左到右 遍历有向无环 基类图,其中 “从左到右”是顺序 基类名称的外观 派生类base-specifier-list。
- 然后,直接基类应该是 按声明顺序初始化为 它们出现在base-specifier-list中 (无论顺序如何 MEM-初始化)。
- 然后,非静止 数据成员应初始化 他们在宣布的顺序 类定义(再次无论如何 mem-initializers的顺序)。
- 最后,构造函数的主体 被执行。 [注:声明 命令是为了确保基础 和成员子对象被销毁 初始化的逆序。 ]
答案 2 :(得分:2)
如果您的问题与标准中的措辞有关,那么您一定是误解了它。确实,各种函数说明符的列表包括关键字virtual
作为一个可能的函数说明符。但是,它在其他方向上不起作用:关键字virtual
不仅限于函数说明符。它有其他用途。您已经找到了一个示例 - 它可以用于声明虚拟基类。
答案 3 :(得分:1)
这是虚拟继承,请查看here以获得解释。
常见的用法是,如果你有一个继承自2个B和C类的A类,它们继承自同一个祖先D.这对于正常继承是有问题的,因为A将包含两个D的实例,所以应该使用一个。使用虚拟继承,例如C从D继承虚拟,A的C部分中的D实例的地址在vmt中找到,因此它可以指向B部分正在使用的相同实例
答案 4 :(得分:0)
virtual inheritence它用于指定当存在多个继承时继承如何工作。基本上它允许你有'钻石'无效图,而不是非虚拟图,它会给你一棵树,在树叶上留下多个基础条纹(引发了潜在的歧义问题)。