基类对象是不是隐式添加到派生类?
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...
;
那么在上面的代码中,anint
、afloat
是Base
的子对象吗? anint
和 afloat
也是 Derived
的子对象吗?并且是否还向Derived
添加了一个看起来像Base something
的成员?所以最后Derived
有三个子对象:anint
、afloat
和Base 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 的子对象。 - 结尾 例子 ]
术语子对象更普遍地使用,因为继承不是形成聚合类型的唯一方法。您可以将成员添加到类中,这些成员也将是子对象。而当你形成数组时,每个元素都是整个数组的一个子对象。
解决您对问题的更新:
那么在上面的代码中,
anint
、afloat
是Base
的子对象吗?
是的。它们是Base
的成员,因此是它的子对象。它们的内存位置位于Base
对象的内存中。
anint
和afloat
也是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 - 我确实了解相关标准的部分内容。我说我不理解你的困惑(或你试图说明它)。子对象明确表示“作为较大对象一部分的对象”。它有多种形状和形式。继承仅嵌入类类型的子对象。当然,这是传递的。如果a
是Base
的子对象并且Base
是Derived
的子对象,则a
是Derived
的子对象。即使无法访问也是如此。【参考方案2】:
但这是否意味着每当一个类有一个基类时,编译器就会在派生类中隐式添加一个基类类型的对象?
是的。这就是派生类的意义,同时可以访问该基子对象的受保护成员,并且可以隐式转换为该基子对象。
【讨论】:
以上是关于基类对象是不是隐式添加到派生类?的主要内容,如果未能解决你的问题,请参考以下文章