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

时间:2017-08-21 08:16:16

标签: c++

我刚刚在标准中读到了关于子对象的内容:

  

子对象可以是成员子对象(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子对象是Baseanintafloat也是Derived的子对象吗?是否还添加了一个Derived的成员,看起来像Base something?最后,Derived有三个子对象:anintafloatBase something

2 个答案:

答案 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对象的内存中。

  

Baseanint也是afloat的子对象吗?

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

  

是否还添加了Base的{​​{1}}成员?

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

  

所以最后,Derived有三个子对象:anint,afloat和Base something?

是。看起来有点像这样:

Derived

答案 1 :(得分:0)

  

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

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