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 定义的一部分,而不是编译器的私有规则(也就是说,一个平台上的所有编译器都必须使用相同的规则),但这些东西的顺序可能因实现而异。
给定以下示例:
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 定义的一部分,而不是编译器的私有规则(也就是说,一个平台上的所有编译器都必须使用相同的规则),但这些东西的顺序可能因实现而异。