【问题标题】:What is the difference between these two types of return? [duplicate]这两种退货方式有什么区别? [复制]
【发布时间】:2020-08-13 04:16:02
【问题描述】:

我有空课(仅举例):

class A { ; };

我尝试了两种在函数中创建新的 A 类对象并返回:
1)

A getA1()
{
    A a;
    return a;
}

2)

A getA2()
{
    A* a = new A;
    return *a;
}

如果我得到相同的结果,它们之间有什么区别?

【问题讨论】:

  • 如果我得到相同的结果,它们之间有什么区别? -- 编写一个正确使用这两种方法的main 程序,即没有内存泄漏。你不能用第二种方法做到这一点。如果您的代码泄漏内存,“结果”有什么好处?
  • @Alex 提示:添加析构函数到 out ~A() { std::cout
  • -O3 下的 Clang 编译为 ret。 :)
  • 第二个性能较差,会泄漏内存。第一个不会。
  • 据我了解getA1() 函数我无法释放内存,因为它是在程序启动之前分配的。在getA2()函数处内存分配是动态的,在程序执行之前不会分配?

标签: c++ return-value


【解决方案1】:

这个问题实际上可以深入研究 C++ 中内存管理的可怕内部工作原理。我不确定你对这一切有多熟悉,所以我会尝试用简单的方式回答。

从表面上看,这两个函数做同样的事情。您构造一个新对象,然后返回该对象。但是,两者之间的主要区别在于 这些对象的存储位置。

在第一个示例中,您所做的是返回您之前在函数中创建的对象 A 的副本。 (如果您知道什么是复制构造函数,那么当您运行 return a; 时就会调用它。)对此有一些警告(如果您有兴趣,请查找“复制省略”),但您应该认为这只是返回一个普通的旧对象,与您声明的任何其他变量没有什么不同。

然而,在第二个示例中,您动态分配一个名为 a 的新对象。像这样分配的对象存储在中,而不是堆栈中,任何分配的对象最终都需要被释放。如果不是,那么这会导致内存泄漏。假设这个程序的用户在程序退出之前会知道或记住delete 这个变量是不安全的,因此返回这样一个动态分配的指针几乎不是一个好主意。

tl;dr 第二个有能力破坏你电脑的内存。

如果你想了解更多的区别并且不熟悉 C++ 中的内存,你一定要研究“C++ 指针”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    相关资源
    最近更新 更多