【问题标题】:C++ Object Creation and Memory AllocationC++ 对象创建和内存分配
【发布时间】:2014-03-31 23:41:00
【问题描述】:

假设我有一个简单的 Movie 对象,它只跟踪名称、长度和成本的一些数据成员。

如果在我的驱动程序文件中,我会创建一个 Movie 对象。哪个是首选和区别:

Movie firstMovie = Movie("Titanic", 126, 13.2);

Movie* firstMovie = new Movie("Titanic", 126, 13.2);

我认为后者是如果我们需要访问这个对象,如果要执行它所在的方法。换句话说,如果创建的第一个对象像在方法中那样初始化,那么一旦方法执行完毕,我们将失去任何连接,因为没有为它分配内存。我的思维方式正确吗?这不是家庭作业,更多的是自从我从 Java 过渡以来一直潜伏的问题。谢谢。

【问题讨论】:

  • 第二段代码需要Movie* firstMovie = new Movie("Titanic", 126, 13.2);才能编译。
  • 谢谢,我会编辑那个更改。
  • 第一个将通过堆栈分配。而第二个将在堆上分配。如果您已通过堆分配它,则必须手动删除它。在堆栈上,删除将自动发生。

标签: c++ oop object initialization


【解决方案1】:

我想你明白两者之间的区别很好。相反,问题是“我应该更喜欢哪个?”就个人而言,如果我能侥幸逃脱,我更喜欢把东西放在堆栈上。现在您的堆栈足够大,除非您有其他错误,否则您不会出现堆栈溢出,并且将东西放在堆栈上意味着(1)不需要手动 delete 它,(2)它更有可能在内存缓存中而不是在堆中,并且 (3) 分配内存的速度尽可能快。

但是,有时您无法摆脱它。在这些情况下,请继续将东西放在堆上。

Gosling 奇怪地坚持使用 new 来表示“让我成为一个对象”。 Java 文档总是吹嘘你如何不需要 deletenew-ed 的东西(因为垃圾收集器),但似乎从来没有提到在 C++ 中你不必 new 事情了几乎和 Java 一样频繁。

【讨论】:

    【解决方案2】:

    首先,你应该写:

    Movie firstMove("Titanic", 126, 13.2); // Created on the stack
    Movie *pFirstMovie = new Movie("Titanic", 126, 13.2); // Created on the heap
    

    否则你创建一个对象,然后将它复制到 firstMovie,这意味着你需要一个复制构造函数。

    主要区别在于第一个示例在堆栈上创建一个对象,而第二个示例在堆上创建它。当您退出创建对象的函数时,堆栈上的对象将被销毁,对该对象的任何引用都将变为无效。

    所以,如果你只需要在函数内使用对象,那么对象最好在栈上创建,这样你就不用担心内存泄漏了。

    但是,如果您想在其他地方使用该对象,最好使用 new 运算符在堆上创建它。您可以随意传递引用,但需要记住以后删除它。

    在堆上创建对象的另一个优点是,当您需要大量数据或进行递归时,堆栈空间的运行速度将比堆空间不足的速度快得多。

    【讨论】:

    • When you exit the function where the object was created the objects on the heap will be destroyed and any reference to this object will become invalid 堆栈变量不会发生这种情况吗?
    • @uncletall:编译器已经优化了一天,所以在这种情况下复制构造函数不会被调用。
    • @Smeet:我会说依赖编译器特定的行为是非常糟糕的做法
    【解决方案3】:

    将为两者分配内存:

    Movie firstMovie("Titanic", 126, 13.2);

    Movie* firstMovie = new Movie("Titanic", 126, 13.2);

    不同之处在于,一旦超出范围,第一个将被销毁,而第二个将保持不变,直到您单独删除。第二种方法称为动态内存分配,内存将在heap 中分配,第一种情况下,内存将在stack 中分配。

    【讨论】:

      【解决方案4】:
      Movie firstMovie = Movie("Titanic", 126, 13.2);
      

      您正在通过调用构造函数创建一个对象,该构造函数又被分配给firstMovie。 更好的方法是

      Movie firstMovie("Titanic", 126, 13.2);
      

      第二种情况

      Movie* firstMovie = new Movie("Titanic", 126, 13.2);
      

      您正在堆上动态创建一个对象,一旦不再需要该对象,您需要使用delete 删除该对象。

      delete firstMovie;

      【讨论】:

        【解决方案5】:

        您可以像这样简单地实例化对象:

        Movie firstMovie ("Titanic", 126, 13.2);

        在初始化原始指针时必须使用 new 关键字。

        Movie *firstMovie = new Movie("Titanic", 126, 13.2);

        不同之处在于指针对象在访问成员函数时使用->,而另一个对象使用. 表示法。并且指针对象分配在堆中,而另一个分配在堆栈中。

        【讨论】:

          猜你喜欢
          • 2012-02-21
          • 1970-01-01
          • 2023-03-18
          • 2012-01-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多