繁体   English   中英

当新的 object 分配给它的地址时,object 是否必须销毁?

[英]Does object have to be destroyed when a new object is assigned to its address?

考虑以下代码。

#include <stdio.h>
using namespace std;

constexpr size_t TOTAL = 2;

class thing
{
private:
    inline static size_t NEXT_ID = 0;
    size_t id;

public:
    thing() : id(NEXT_ID++)
    {
        printf("Thing %zd created.\n", this->id);
    }
    ~thing()
    {
        printf("Thing %zd destroyed.\n", this->id);
    }
};

class container
{
private:
    inline static size_t NEXT_ID = 0;
    size_t id;
    thing* things;

public:
    container() : id(NEXT_ID++)
    {
        this->things = new thing[TOTAL];
        printf("Container %zd created.\n", this->id);
    }
    ~container()
    {
        delete[] this->things;
        printf("Container %zd destroyed.\n", this->id);
    }

    thing& at(size_t idx)    // this is the important method
    {
        return this->things[idx];
    }
};

int main()
{
    container c;
    c.at(0) = thing();   // here is the problem
    return 0;
}

output 是我没想到的。

Thing 0 created.
Thing 1 created.
Container 0 created.
Thing 2 created.
Thing 2 destroyed.
Thing 1 destroyed.
Thing 2 destroyed.
Container 0 destroyed.

我知道Thing 2是一个临时的 object,这就是它被摧毁两次的原因。 关于Thing 0发生的事情,我有几个问题。

  • 为什么Thing 0没有被摧毁?
  • 会不会有 memory 泄漏?
  • 我必须以某种方式破坏Thing 0还是成功覆盖?

没有对同一个 object 的析构函数的双重调用。 问题仅出在您的 output 中。 您正在打印idc.at(0) = thing();中的副本分配将临时 object 中的id复制到容器中的那个。 这就是你看到两个“事物 2 被摧毁”的原因。 并且没有“Thing 0 被破坏。”。

如果您想要更好的日志记录机制,您可以打印this指针。 object 的地址在 object 的生命周期内不会改变,它是 object 的唯一标识符。 当然,为方便起见,您还可以打印id

printf("Thing %p %zd created.\n", static_cast<void*>(this), this->id);
printf("Thing %p %zd destroyed.\n", static_cast<void*>(this), this->id);

这应该会给你一些像这样的 output (当然 0x11111111、0x22222222 和 0x33333333 在你的情况下看起来会有所不同):

事物 0x11111111 0 已创建。
事物 0x22222222 1 已创建。
容器 0 已创建。
事物 0x33333333 2 已创建。
东西 0x33333333 2 被破坏。
东西 0x22222222 1 被破坏。
东西 0x11111111 2 被破坏。
容器 0 被破坏。

在这份声明中

c.at(0) = thing();

这里使用了由编译器复制赋值运算符隐式定义的。 因此,由表达式c.at(0)引用的 object 的数据成员id变为等于由表达式thing()创建的临时2的 ID。

在此语句中,临时 object 被创建并最终被销毁

Thing 2 created.
Thing 2 destroyed.

现在 object c包含两个作为数组元素存储thing子对象。 子对象具有 id(s) 21

它们以与创建它们相反的顺序被删除

Thing 1 destroyed.
Thing 2 destroyed.  // previously it has id equal to 0

所以程序没有 memory 泄漏。 从程序 output 可以看出,所有创建的对象都已成功删除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM