【问题标题】:What is a base class subobject?什么是基类子对象?
【发布时间】:2021-12-12 18:02:40
【问题描述】:

我知道子对象是成员子对象基类子对象数组。 我找不到任何能明确解释前两个术语的东西。以以下代码为例:

struct A{int a;};
struct B{int b;};
struct C:public A,public B{};

我认为:int a 是可能的、尚未实例化的 A 类型对象的成员子对象; int a 是一个可能的、尚未实例化的 C 类型对象的基类子对象。对吗? 成员子对象基类子对象的定义是什么?可以举个例子吗?

【问题讨论】:

  • "我知道子对象是成员子对象、基类子对象和数组。"你从哪里得到这些条款的? 那个来源对这些条款有什么看法?
  • 不,aA 类的成员(它也是 C 类的成员,因为 C A)。没有“成员子对象”这样的东西。
  • "对象可以包含其他对象,称为子对象。子对象可以是成员子对象 (11.4)、基类子对象 (11.7) 或数组元素。" 6.7.2(对象模型)C++ ISO草案2020

标签: c++ class


【解决方案1】:

每当一个类从另一个类继承时,它也会继承该类的一个实例:

class A { };
class B : A { };

那么 B 类内部看起来像:

class B
{
    A a; // <- implicit base class sub-object, not visible to you
};

请注意,在某些情况下,A 甚至可能不止一个!

class A { };
class B : A { };
class C : A { };
class D : C, B { };

D 然后内部看起来像:

class D
{
    B b; // { A a; }
    C c; // { A a; }
};

bc 是基类子对象;或以扁平化表示:

class D
{
    A aFromB;              // inherited from B, but not a sub-object of D itself
    // other members of B
    A aFromC;              // inherited from C, again not a sub-object of D
    // other members of C 
};

BC 基类子对象在此表示中不可见,但它们仍然以各自的 A 实例与各自的其他成员结合的形式存在(想想周围有大括号)。

如果你想避免A 的重复,你需要虚拟继承:class B : virtual A { }——所有虚拟继承(直接或间接)的A 实例然后合并为一个实例(尽管如果没有- 虚拟继承的这些仍然与组合的并行),请考虑:

class A { };
class B : A { };
class C : virtual A { };
class D : virtual A { };

class E : A, B, C
{
    A combinedAFromCAndD;
    // other members of B
    // other members of C
    A separateAFromD
    // other members of D
};

注意:以上这些布局只是示例,具体布局可能会有所不同。

【讨论】:

  • 澄清了很多。但是当您编写 D 类内部的样子时,B bC c 不会是 D 实例的子对象成员吗?我想我现在缺少成员子对象定义......
  • B bC c 是——就像在第一个例子中一样——基类子对象,同样你实际上看不到它们——除此之外你可以访问它们(非私有)成员就好像它们是继承类的一部分一样,即this-&gt;someFunction() 而不是this-&gt;b.someFuntion()
  • 你知道我在哪里可以找到更多关于它的信息吗?我在 Bjarne 的 C++ 编程语言、Alexandrescu 的现代 C++ 设计中搜索了这个术语,但没有找到任何东西,草案在这个主题上让我不知所措,而且它没有提供明确的定义(至少我找不到它们)
  • 任何好的C++ book(不过,可能会跳过内存布局部分,您可能会发现this question 很有趣)。搜索词以获取更多信息的候选可能是inheritancevirtual inheritancememory layout 以及它们的组合——当然,所有这些都与c++ 相结合......
【解决方案2】:

在您的代码中,C 实例的基类子对象是其中包含的 AB 的实例。这些子对象中的每一个都有一个子对象本身(ab);这些不被视为C 实例的子对象(因为它们是子对象的子对象),但被视为C 实例的“嵌套对象”。

【讨论】:

  • 我宁愿说“(类)成员”而不是“嵌套对象”。
  • @Fareanor 当然,但是“嵌套对象”还包括例如类成员的成员,它们不是(外部类的)类成员。该术语包含“B 位于 A 的分配内”的所有实例。
  • @Fareanor OP 特别关注涵盖对象的标准部分,包括类类型的对象,但也包括数组。该部分正式定义了“嵌套在”概念,使得a 被“嵌套在”C 的实例中。它还将成员子对象定义为与基类子对象不同,这意味着aC 的“类成员”,但它不是C 实例的“成员子对象” .
  • @Roman 我不确定你想让我写什么代码。人们会非常广泛地使用“子对象”这个术语,而不是以标准使用它的特定、有限的方式,所以如果你试图匹配这些定义,它是行不通的。
  • @Roman 正确。但请注意,正式术语“成员子对象”(或一般的子对象)并未被广泛使用,它主要被标准用于定义递归概念(例如,一个对象只有在其所有子对象都是 POD 时才是 POD)。跨度>
猜你喜欢
  • 2014-11-07
  • 1970-01-01
  • 2018-12-16
  • 1970-01-01
  • 2021-07-17
  • 1970-01-01
  • 2011-05-26
  • 1970-01-01
  • 2014-02-25
相关资源
最近更新 更多