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

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

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

【问题讨论】:

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

标签: c++ inheritance space


【解决方案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 我们是在谈论语言是如何定义的,还是编译器是如何实现的?从概念上讲,如果需要先初始化内存,那么以后就不能再分配它了,不是吗?大多数/所有编译器选择为所有数据分配一个块的事实是一个工件。但是,当然,如果您表明规范规定了它,那么我会全神贯注。在此之前,我会说是的,需要在派生类之后分配基类。
    猜你喜欢
    • 1970-01-01
    • 2016-12-20
    • 2016-07-19
    • 2018-07-16
    • 1970-01-01
    • 2015-11-03
    • 2018-07-21
    • 2021-06-25
    • 2015-08-18
    相关资源
    最近更新 更多