我刚刚在标准中读到了关于子对象的内容:
子对象可以是成员子对象(9.2),一个基础 class subobject(Clause 10),或数组元素。
在阅读有关C ++的情况下,我遇到了很多情况,其中提到了子对象,甚至没有派生类中的子对象(显式定义)。
但这是否意味着每当一个类有一个基类时,编译器会在派生类中隐式添加一个基类类型的对象?
像:
class Base
{
};
class Derived : Base
{
};
所以在Derived中添加了Base的子对象?
标准中是否有我应该阅读的内容?我知道这是一个非常小的引用。
更新
如果我们有这些课程:
class Base
{
int anint;
float afloat;
};
class Derived : Base
{
//inherited member variables...
};
因此,在上面的代码中,anint
的{{1}},afloat
子对象是Base
? anint
和afloat
也是Derived
的子对象吗?是否还添加了一个Derived
的成员,看起来像Base something
?最后,Derived
有三个子对象:anint
,afloat
和Base something
?
答案 0 :(得分:4)
嗯,是的。派生类最多的类将包含它派生自的每个类的子对象。引用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的对象将具有类的子对象 派生,而后者将拥有类Base的子对象。 - 结束 示例]
术语子对象更常用,因为继承不是形成聚合类型的唯一方法。您可以向类添加成员,这些也是子对象。当你形成数组时,每个元素都是整个数组的子对象。
解决您对问题的更新:
因此,在上面的代码中,
anint
的{{1}},afloat
个子对象是什么?
是。它们是Base
的成员,因此是它的子对象。它们的内存位置放在Base
对象的内存中。
Base
和anint
也是afloat
的子对象吗?
是的,因为包含是传递性的。 Derived
包含Derived
的子对象。
是否还添加了
Base
的{{1}}成员?
Derived
子对象没有命名成员。 Base
对象中只有一块内存,其中构造有Base
个对象。
所以最后,Derived有三个子对象:anint,afloat和Base something?
是。看起来有点像这样:
Derived
答案 1 :(得分:0)
但这是否意味着每当一个类有一个基类时,编译器会在派生类中隐式添加一个基类类型的对象?
是。这就是作为派生类的原因,同时可以访问该基础子对象的受保护成员,并且可以隐式转换为该基础子对象。