2

给定以下示例:

class A
{
    protected:
        static void useful_function_without_side_effects() {...}
}

class B : private A
{
    // B has no friends :(

    public:
        void travel_back_in_time() { super_useful_function(); }
}

问题 1:是否允许编译器优化基类 A,因为这个基类不能真正影响 B 或它的运行时行为?

问题 2:如果继承像这样声明为 private virtual,这种情况会改变吗?

class B : private virtual A
4

1 回答 1

1

答案1:

非多态类在运行时完全没有代表。唯一可能存在的是对象和方法,它们被视为函数。该类仅指示编译器访问对象的某些部分并以定义的方式调用 resolve 方法。一旦直接解决,一切都在运行时代码中硬编码。限定符在private这里没有任何改变。

B 派生的 A 类(没有字段)不会向 B 类的对象“增加大小”,这应该是您的问题。如果 A 类没有字段,则始终如此,但 sizeof(A) 至少始终为 1。尽管也没有这样的规则,即 B 的大小必须是所有字段和基类的大小之和。

答案 2

这增加了 B 类的大小。该标准并没有精确的方式。在典型的实现中,它总是将 B 类的大小扩展一个指针的大小,再加上 A 类的任何可能大小。

通常,虚拟继承是使用“指向自身的指针”来实现的。也就是说,派生类 (A) 的子对象在物理上是整个对象的一部分,但它永远不会直接访问,而是通过整个对象中的指针来访问。

当您拥有总大小为 4 的无字段 A 和 B 时,这种情况就更少了:

物理遗传:

B: [A: 0] [B extension: 4]

虚拟继承:

B: [A virtual: <pointer size>] [B extension: 4] [A shared subobject: 1]

这些事情的顺序在不同的实现中可能有所不同,尽管它是 ABI 定义的一部分,而不是编译器的私有规则(也就是说,一个平台上的所有编译器都必须使用相同的规则)。

于 2015-04-14T13:25:47.080 回答