基类对象是不是隐式添加到派生类?

Posted

技术标签:

【中文标题】基类对象是不是隐式添加到派生类?【英文标题】:Are base class objects implicitly added to derived classes?基类对象是否隐式添加到派生类? 【发布时间】:2017-08-21 08:16:15 【问题描述】:

我刚刚读到标准中的 子对象 是这样说的:

子对象可以是成员子对象 (9.2)、基础 类子对象(第 10 条)或数组元素。

我在阅读 C++ 时遇到过很多情况,其中提到了子对象,而派生类中甚至没有子对象(显式定义)。

但这是否意味着每当一个类有一个基类时,编译器就会在派生类中隐式添加一个基类类型的对象?

喜欢:

class Base

;
class Derived : Base

;

所以在Derived中添加了Base的子对象?

标准中有什么我应该阅读的吗?我知道这是一个非常小的引用。

更新:

如果我们有这些课程:

class Base

int anint;
float afloat;
;
class Derived : Base

//inherited member variables...
;

那么在上面的代码中,anintafloatBase 的子对象吗? anintafloat 也是 Derived 的子对象吗?并且是否还向Derived 添加了一个看起来像Base something 的成员?所以最后Derived有三个子对象:anintafloatBase something

【问题讨论】:

继承是一种“is-a”关系。在您的示例中,类Derived 是一个 Base。确切的实现方式无关紧要,但是(再次以您的示例为例)Base 的所有成员也是Derived 的成员。 如果您添加一些数据字段,您的示例会更清晰。 我认为class Derived : Base应该归类为显式加法。除了 vtable 之外,似乎没有办法将任何字段隐式添加到类中。 @Someprogrammerdude 是的,但更关心的是基类类型的对象是否在派生类中隐式定义,例如对象Base obj; 是否实现Derived 的定义? 【参考方案1】:

嗯,是的。最派生的类将包含它派生的每个类的子对象。引用 C++17(n4659 草案),[class.derived/3]:

base-specifier-list 指定基类的类型 派生类类型的对象中包含的子对象。 [ 示例:

struct Base 
  int a, b, c;
;
struct Derived : Base 
  int b;
;
struct Derived2 : Derived 
  int c;
;

这里,类 Derived2 的对象将有一个类的子对象 Derived 又将具有类 Base 的子对象。 - 结尾 例子 ]

术语子对象更普遍地使用,因为继承不是形成聚合类型的唯一方法。您可以将成员添加到类中,这些成员也将是子对象。而当你形成数组时,每个元素都是整个数组的一个子对象。


解决您对问题的更新:

那么在上面的代码中,anintafloatBase 的子对象吗?

是的。它们是Base 的成员,因此是它的子对象。它们的内存位置位于Base 对象的内存中。

anintafloat 也是 Derived 的子对象吗?

是的,因为包含是传递性的。 Derived 包含Base 的子对象。

是否还向Derived 添加了一个看起来像Base 的成员?

Base 子对象没有命名成员。 Derived 对象内只有一块内存,其中构造了 Base 对象。

所以说到底,Derived 有三个子对象:anint、afloat 和 Base 什么的?

是的。看起来有点像这样:

+----------------------+
|+--------------------+|
|| int    |   float   ||
|+--------------------+|
| Base object (unnamed)|
+----------------------+
  Derived object

【讨论】:

谢谢!那么,例如,Derived 真的在其定义中隐式实现了 Base obj; 我真的很喜欢你的引用,但我仍然不确定“子对象”是否都是从基类继承的所有对象,这些对象已经在基类的定义中明确定义,并且是派生类定义中包含的基类。或者只有第一个或第二个。 @sdsadasdasd - 我承认我不明白不清楚的部分。标准中的示例非常明确。 Derived 包含一个 Base 子对象,这是给定的。 Derived2 包含一个 Dervied 子对象,然后由于包含是传递性的,它还包含一个 Base 子对象,它嵌套在 Derived 子对象中。总而言之,Derived2 将有 5 个整数的空间。 @sdsadasdasd:Base obj 假设中最大的错误是假设 Base 类子对象有名称。 @sdsadasdasd - 我确实了解相关标准的部分内容。我说我不理解你的困惑(或你试图说明它)。子对象明确表示“作为较大对象一部分的对象”。它有多种形状和形式。继承仅嵌入类类型的子对象。当然,这是传递的。如果aBase 的子对象并且BaseDerived 的子对象,则aDerived 的子对象。即使无法访问也是如此。【参考方案2】:

但这是否意味着每当一个类有一个基类时,编译器就会在派生类中隐式添加一个基类类型的对象?

是的。这就是派生类的意义,同时可以访问该基子对象的受保护成员,并且可以隐式转换为该基子对象。

【讨论】:

以上是关于基类对象是不是隐式添加到派生类?的主要内容,如果未能解决你的问题,请参考以下文章

继承中的基类是不是复制到派生类?

C++中的派生类,可以不定义对象直接调用基类的成员和调用自己的成员函数嘛???

在基类对象内部创建派生类对象

<继承问题>可以把基类对象赋值给子类对象么?

检测基类对指向派生类的引用的分配

使用基类指针查找派生类对象的大小