【问题标题】:why my local object destroyed twice?为什么我的本地对象被破坏了两次?
【发布时间】:2011-05-20 17:00:18
【问题描述】:

我有一个返回本地对象的函数:

class AT
{
public:
    AT() { cout<<"construct"<<endl; }

    AT(const AT& at) { cout<<"copy"<<endl; }

    ~AT() { cout<<"destroy"<<endl; }
};

AT funcAt()
{
    AT tmp;
    return tmp;
}
...
funcAt();

输出是:

construct
copy
destroy
destroy

我想只有“tmp”的构造和销毁,那么为什么会有复制和另一个销毁呢?复制的对象在哪里?

【问题讨论】:

  • 任何 C++ 对象都不能被销毁(或创建)两次。
  • 如果您运行启用了优化的发布版本,我将保证输出更改。
  • @Neil:我敢打赌我可以创建和销毁同一个对象两次。 (作者:迂腐警察)
  • @Martin 你能两次(甚至一次)踏入同一条河流吗?如果是这样,请发布一个答案来证明它。
  • @Neil:创建一个普通对象。显式调用析构函数。然后调用placement new来重新初始化对象,然后当对象超出范围时将调用普通的析构函数。同一对象构造和销毁两次。

标签: c++ return-value


【解决方案1】:

让我们稍微充实一下:

AT funcAt()
{
    AT tmp;           [1]
    return tmp;       [2]
}                     [3]
...
funcAt();             [4]

[1] 在 tmp 中创建一个 AT 对象
[2] 复制tmp到返回值
[3] 销毁tmp
[4] 因为没有使用所以销毁返回值

【讨论】:

    【解决方案2】:

    因为是

    1) 创建:AT tmp 在 funcAt
    2) 复制:return tmp;,这是因为函数返回一个副本:AT funcAt()
    3) destroy - 第一个 tmp 对象,以及返回的副本

    提示:注意输出中的copy :)

    【讨论】:

    • 我明白你的意思,但你需要清理它以指定两个对象被销毁,而不是同一个对象两次。
    【解决方案3】:

    原因是tmp的副本是从funcAt返回的,没有存储在任何地方,因此C++销毁它并调用析构函数

    【讨论】:

    • “保存在任何地方”对初学者来说有点混乱,我想。它并没有真正描绘出正在发生的事情。
    • @San 我已将已保存切换到已存储。想不出比这更好的词了
    【解决方案4】:

    tmp 被构造和销毁。对于返回值(它是一个新对象,而不仅仅是一个引用)也是如此,尽管这里使用了 cop 构造函数。您没有看到正在使用的返回值,但它仍然通过了。

    【讨论】:

      【解决方案5】:

      函数的返回值是函数内部使用的本地对象的单独对象(即副本)。

      【讨论】:

        猜你喜欢
        • 2014-09-17
        • 1970-01-01
        • 2016-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-11
        • 1970-01-01
        相关资源
        最近更新 更多