C++ 标准对子对象 有明确的定义。也就是说,很多人在谈论 C++ 时(准确地说)并没有使用标准的语言。一个流行的例子是术语object。在 Java 等语言中,有些人倾向于仅在 类的实例 的意义上使用 object,这不适用于int。在 C++ 标准中,int 是一个对象。
标准在 [intro.object]/2 中所说的:
对象可以包含其他对象,称为子对象。子对象可以是成员子对象、基类子对象或数组元素。不是任何其他对象的子对象的对象称为完整对象。
这是在(可能的)内存布局的上下文中理解的。它没有完全指定,但很可能看起来像这样:
class Foo { int i; };
class Bar : public Foo { int j; };
Bar 类型的对象在内存中可能如下所示:
+-酒吧-------------------+
| +-Foo-----+ |
| |诠释我 |诠释 j; |
| +---------+ |
+------------------------+
即Foo 的成员是Bar 的成员,就像Bar 的直接成员一样。因此,Bar 的每个对象都“包含”Foo 类型的对象。还要考虑
Bar b;
Bar* pBar = &b;
Foo* pFoo = &b;
+-酒吧-------------------+
| +-Foo-----+ |
| |诠释我 |诠释 j; |
| +---------+ |
+--^--------------------+
^ |pFoo
|pBar
为了允许pFoo 指向Foo 类型的完整对象和Foo 类型的子对象,需要有一个完整且(内存方面)独立的Foo 类型的对象内部的任何对象输入Bar。在编译时可能不知道是哪种情况,但为pFoo->i = 5; 生成的代码必须同时适用于这两种情况。
这一切都是在 as-if 规则下指定的,即它不必是那样的,但它必须以可观察的方式表现。此外,这不是实际的内存布局,但它是一个常见的实现。
在 [intro.object]/4 中
如果完整的对象、数据成员或数组元素是类类型,则其类型被认为是最派生类,以区别于任何基类子对象的类类型;最派生类类型或非类类型的对象称为最派生对象。
除了supersede 和superset 之外,标准中没有使用super 这个词。有基类和派生类(还有~对象)。
在 C++ 语言标准之外,术语超类用来指代一个基类,而术语子类用来指代到一个派生类。这指的是面向对象的概念和分类,就像物种是生物学中属的子类别。
但是在这个分类中,没有内存布局,因此没有必要谈论子对象。有 instances 或 objects(在 OO 意义上)类,所以你可以谈论 超类的对象 和子类的对象。混淆可能源于将这个 子类的对象 缩写为 subobject,并将 OO 语言与 C++ 标准中的语言混合。