给出以下示例:
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
答案 0 :(得分:1)
非多态类在运行时完全没有代表。唯一可能存在的东西是对象和方法,它们被视为函数。该类仅指示编译器访问对象的某些部分,并按照定义的方式解析方法调用。直接解析后,所有内容都在运行时代码中进行了硬编码。 private
限定符在此处没有任何更改。
由B派生的A类(没有字段)不会"添加大小"对于B类的对象,这应该是你的问题。如果A类没有字段,则总是如此,但sizeof(A)将始终为1。虽然也没有这样的规则,B的大小必须是所有字段和基类的大小的总和。
这会增加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>