基类和派生类构造函数的内存分配
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 我们是在谈论语言是如何定义的,还是编译器是如何实现的?从概念上讲,如果需要先初始化内存,那么以后就不能再分配它了,不是吗?大多数/所有编译器选择为所有数据分配一个块的事实是一个工件。但是,当然,如果您表明规范规定了它,那么我会全神贯注。在此之前,我会说是的,需要在派生类之后分配基类。以上是关于基类和派生类构造函数的内存分配的主要内容,如果未能解决你的问题,请参考以下文章