C++ 可以(虚拟)私有基 类 被编译器删除吗?

C++ can (virtual) private base classes be removed by the compiler?

给定以下示例:

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:是否允许编译器优化基数 class A,因为这个基数 class 不能真正影响 B 或者它是 运行-时间以任何方式表现?

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

class B : private virtual A

答案 1:

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

B 派生的 A class(没有字段)不会 "add size" 到 class B 的对象,这应该是你的问题。如果 A class 没有字段,这始终为真,但 sizeof(A) 至少始终为 1。虽然也没有这样的规则,即 B 的大小必须是所有字段的大小和基数 classes.

的总和

答案 2

这会增加 B 的大小 class。该标准没有明确说明是什么方式。在典型的实现中,它总是将 B class 的大小扩展一个指针的大小,加上 class A.

的任何可能大小

通常使用 "pointer to itself" 实现虚拟继承。即derived的子对象class(A)在物理上是整体对象的一部分,但从不直接访问,而是通过整体对象中的指针访问。

当你有总大小为 4 的无字段 A 和 B 时,这种情况更多:

物理继承:

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

虚拟继承:

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

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