基类和派生类构造函数的内存分配

Posted

技术标签:

【中文标题】基类和派生类构造函数的内存分配【英文标题】:Memory allocation of base class and derived class constructor 【发布时间】:2012-08-22 00:19:59 【问题描述】:

派生类对象创建时先为哪个分配空间?

是基类构造函数还是派生类构造函数?

【问题讨论】:

Base first, see here for more detail @close-voter:不,分配与初始化不同。不要根据你不知道的感觉对事情进行投票。只对你知道的事情投票。 @Cheersandhth.-Alf (首先,不,我不是最接近投票者)我根据关于分配术语和初始化可能在问题中混淆了,因此链接......也许不是。无论如何,我发现您在下面的回答内容丰富,+1 【参考方案1】:

首先,

allocation,您所询问的内存预留,不同于 initialization 并且在 initialization 之前(执行一个在那段记忆),以及

正式(我们的神圣标准)和实践在大多数派生对象的内存是否需要连续方面有所不同,正式将“内存区域”定义为可能不连续,主要是为了支持多重虚拟继承。

也就是说,在实践中,最衍生的对象是一个单一的、连续的内存块,其中包括所有基类子对象和数据成员子对象的空间,并且这个块必须分配一下子。

初始化(构造函数的调用)在分配之后进行。如果初始化因抛出异常而失败,new 表达式可保证释放。但是,如果使用的分配函数具有额外的自定义参数(所谓的“新放置”)并且没有相应的释放函数可用,则此保证无效,例如用于微软 MFC 类框架的早期版本中的调试构建(具有讽刺意味的是:初始化失败的程序只会在调试构建中泄漏内存……)。

【讨论】:

一个很好的答案,适合不需要问问题的人;-)【参考方案2】:

派生对象的空间包含所有派生成员和所有基成员。派生对象只有一次分配,分配的内存保存对象的所有部分。

【讨论】:

【参考方案3】:

正如评论中提到的,它是基类。从逻辑上讲,由于您可以访问派生类(包括构造函数)中的基本公共和受保护成员,因此需要先分配它。尝试从以下代码开始并尝试一下。

#include <iostream>

class Base

    public:
    Base() std::cout<<"Base CTOR" << std::endl;
;

class Derived : public Base

    public:
    Derived():Base() std::cout<<"Derived CTOR"<<std::endl;
;

int main(int argc, char* argv[])

    Derived d;

【讨论】:

这段代码着眼于构造顺序,而不是内存分配。 -1 实际上,一个对象的所有内存都被一次性分配为一个单独的块。 @Alf 我们是在谈论语言是如何定义的,还是编译器是如何实现的?从概念上讲,如果需要先初始化内存,那么以后就不能再分配它了,不是吗?大多数/所有编译器选择为所有数据分配一个块的事实是一个工件。但是,当然,如果您表明规范规定了它,那么我会全神贯注。在此之前,我会说是的,需要在派生类之后分配基类。

以上是关于基类和派生类构造函数的内存分配的主要内容,如果未能解决你的问题,请参考以下文章

C++入门派生类和基类的构造/析构函数关系

C++基类和派生类的构造函数

C++基类和派生类的构造函数

C++中派生类的构造函数怎么显式调用基类构造函数?

基类构造函数的派生类成员初始化

类学习