【问题标题】:Dynamic initialization of object with constructor Vs. new in c++?使用构造函数 Vs 动态初始化对象。 C++ 中的新功能?
【发布时间】:2026-01-09 00:40:01
【问题描述】:

这两个语句在对象的动态内存初始化方面有什么区别 :-

类名 *obj = 新类名;

class_name obj = class_name();

【问题讨论】:

    标签: c++ object memory-management dynamic


    【解决方案1】:

    第一个例子大致如下:

    • 调用操作符 new 并在堆上分配内存
    • class_name 的默认构造函数被调用,因此指向的对象被初始化。

    第二个例子:

    • 创建了一个临时对象 A(分配的右侧)。
    • 创建了一个对象 B(默认构造函数;左侧)
    • A 的内容被对象 B 的内容覆盖 - 这是通过调用赋值运算符来完成的
    • A 被破坏。

    编辑:实际上,我为上面的第二个示例编写的内容是不正确的(也许也没有错)。我不知道这里的标准,但是使用 VC12(优化关闭)代码不会创建临时对象。它只是调用堆栈上对象的默认构造函数。如果存在私有赋值运算符,则代码不会编译 - 正如 James 在他的评论中所写的那样。

    【讨论】:

    • 第二个例子的解释是完全错误的。在他的两个例子中都没有没有赋值。
    • 内存可以在堆上分配更正确。新的可能会失败。
    • 除了@JamesKanze所说的,我记得,当复制初始化中双方的类型相同时,必须执行复制省略(即没有临时)。跨度>
    • @Alf 你是对的,我已经忘记了。当类型相同时,没有没有个副本; IIUC,甚至不需要可访问的复制构造函数。
    • @Alf 但是 VC++ 和 g++ 都说需要可访问的复制构造函数。我不确定是我读错了标准,还是他们。
    【解决方案2】:

    第一个动态定义了一个指向class_name的指针 分配该类型的对象,并初始化指针 及其地址。对象本身的生命周期是直到 您明确删除它。如果class_name 有一个默认值 构造函数,即被调用;否则,该对象不是 初始化。

    第二个定义了一个class_name的实例;正式地,它 使用默认值构造该类型的临时 如果定义了一个构造函数,如果没有定义零初始化, 并 copy 从中构造定义的实例。这 但是,允许编译器省略此复制构造 (以及我所知道的一切),并构造定义的对象 直接地。 (它仍然必须验证是否存在可访问的 但是,复制构造函数。)已定义对象的生命周期 直到超出范围。

    一般来说,我们避免使用第一种形式,除非我们真的需要 显式生命周期。

    【讨论】:

      【解决方案3】:

      首先是动态分配的。第二个是静态分配的,但值已初始化。

      【讨论】:

      • 你的意思是在第二种情况下,值将在运行时初始化?
      • 聚合(POD)类的成员将在运行时初始化。如果没有值初始化,POD 对象的成员将不会被初始化。我不知道具有用户定义构造函数的类是否有任何区别。
      【解决方案4】:

      这个:

      class_name *obj = new class_name;
      

      在堆上创建一个对象,您需要通过delete 将其删除以避免内存泄漏。

      这个:

      class_name obj = class_name();
      

      在堆栈上创建一个对象,当对象超出范围时将被删除。

      【讨论】:

      • 但是如果内存会在运行时初始化,不是吗?
      • 是的,对于这两种情况,内存都是在运行时分配和初始化的,而不是在编译时。
      【解决方案5】:

      希望您正确关联了作业/问题文本。这是微妙的。 “动态”与第一个语句中的动态分配无关。

      () 括号确保 C++03 值初始化,这对于 POD 类型意味着归零。没有它(第一条语句),如果类是 POD,则不需要初始化其成员。对于更一般的情况,我必须检查标准,但我认为,既然你知道问题是关于什么的,那你就可以自己做。

      【讨论】: