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

时间:2015-04-14 12:32:09

标签: c++ optimization private-inheritance

给出以下示例:

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:如果继承将被声明为私有虚拟,这会改变吗?

class B : private virtual A

1 个答案:

答案 0 :(得分:1)

答案1:

非多态类在运行时完全没有代表。唯一可能存在的东西是对象和方法,它们被视为函数。该类仅指示编译器访问对象的某些部分,并按照定义的方式解析方法调用。直接解析后,所有内容都在运行时代码中进行了硬编码。 private限定符在此处没有任何更改。

由B派生的A类(没有字段)不会"添加大小"对于B类的对象,这应该是你的问题。如果A类没有字段,则总是如此,但sizeof(A)将始终为1。虽然也没有这样的规则,B的大小必须是所有字段和基类的大小的总和。

答案2

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

通常,虚拟继承是使用"指向自身"的指针实现的。也就是说,派生类(A)的子对象实际上是整个对象的一部分,但它从不直接访问,而是通过整个对象中的指针访问。

当你有无场A和B,总大小为4的字段时,情况更是如此:

物理继承:

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

虚拟继承:

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

这些内容的顺序可能因实现而有所不同,尽管它是ABI定义的一部分,而不是编译器的私有规则(即,一个平台上的所有编译器必须使用相同的规则)。 / p>