如何在 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 |
| |
同一个页面还有其他场景的内存布局,包括多继承和虚继承
我不是 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 | | |
同一个页面还有其他场景的内存布局,包括多继承和虚继承