如何在 C++ 中构造派生 类 中的对象

How are objects from derived classes constructed in C++

我不是 C++ 专家,我主要使用 Java 和 C#。今天一位老师说了一句话让我很困惑。我试图通过做一些研究来验证信息,但我最终更加困惑。

假设我有 class A 和 class B。Class A 是基础 class,B 是从 A 派生的。

现在我已经知道当创建class B 的对象时,会调用class A 的构造函数,然后调用classe B 的构造函数。同样,当 class B 的 and 对象被销毁时,会调用 class B 的析构函数,然后是 class A.

的析构函数

到目前为止,我的理解是 Class B 包含 class A 中的所有内容,除了它的构造函数和析构函数。我认为当一个来自 class B 的对象被构​​建时,内存中只创建了一个对象(类型 A 和 B)。

现在我的老师说当构建 B 时,会创建 2 个单独的对象并以某种方式“链接”在一起:class A 之一,然后是 class B 之一。两个对象都会存在于内存中,直到调用 class B 对象的销毁。然后 class B 对象将在 class A 对象被销毁之前被销毁。

哪个是正确的?

ps 对不起,如果我的英语马马虎虎,那不是我的母语...

编辑:我会尝试改写:

我认为:Class B包含class A的所有属性和方法。当我从class B创建一个对象时,内存中只有1个对象。 class A 的构造函数被调用只是为了初始化我的对象中最初来自 class A 的部分。

老师说:当我从classB创建一个对象时,在内存中创建了2个对象。当我命令销毁我的对象时,首先销毁内存中的 class B 对象,然后销毁同样留在内存中的 class A 对象。老师一直无法阐明 class B 对象如何能够使用 class A 对象的方法和属性。

对我来说,这似乎也意味着内存中某处有一个我不知道并且几乎无法控制的“幽灵对象”。

根据http://www.vishalchovatiya.com/memory-layout-of-cpp-object/#Layout_of_C_Object_With_Inheritance

这两个 classes:

class X {
    int     x;
    string str;
public:
    X() {}
    virtual ~X() {}
    virtual void printAll() {}
};
class Y : public X {
    int     y;
public:
    Y() {}
    ~Y() {}
    void printAll() {}
};

将在内存中表示,以便 Y 的内存布局包含基 class 的数据成员,后跟派生的 class:

的数据成员
      |                              |          
      |------------------------------| <------ Y class object memory layout
      |          int X::x            |
stack |------------------------------|
  |   |              int string::len |
  |   |string X::str ----------------|
  |   |            char* string::str |         
 \|/  |------------------------------|      |-------|--------------------------|
      |           X::_vptr           |------|       |       type_info Y        |
      |------------------------------|              |--------------------------|
      |          int Y::y            |              |    address of Y::~Y()    |
      |------------------------------|              |--------------------------|
      |               o              |              | address of Y::printAll() |
      |               o              |              |--------------------------|
      |               o              |              
------|------------------------------|--------
      |           X::X()             | 
      |------------------------------|       |   
      |           X::~X()            |       |
      |------------------------------|       | 
      |         X::printAll()        |      \|/ 
      |------------------------------|  text segment
      |           Y::Y()             |
      |------------------------------|
      |           Y::~Y()            |
      |------------------------------|
      |         Y::printAll()        |
      |------------------------------|
      |      string::string()        |
      |------------------------------|
      |      string::~string()       |
      |------------------------------|
      |      string::length()        |
      |------------------------------|
      |               o              |
      |               o              |
      |               o              |
      |                              |

同一个页面还有其他场景的内存布局,包括多继承和虚继承