You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新对象赋值至已有对象地址时需销毁原对象吗?及相关代码疑问

问题解答:对象赋值时原对象的销毁与内存问题

先看你的代码和输出,核心问题在于你误解了赋值操作和对象销毁的区别,我们逐个拆解你的疑问:

1. 为什么Thing 0看起来没被销毁?

其实它已经被销毁了,只是你认不出它了😉。具体原因:

  • 当执行c.at(0) = thing();时,你创建了一个临时thing对象(Thing 2),C++的默认赋值运算符会把这个临时对象的id成员拷贝给原有的Thing 0——这时候原Thing 0的id已经被覆盖成2了。
  • 当容器c的析构函数执行delete[] this->things时,会销毁数组里的两个thing对象:第一个是被修改了id的原Thing 0(现在id是2),所以打印Thing 2 destroyed;第二个是原Thing 1,打印Thing 1 destroyed。

你看到的最后那个Thing 2 destroyed,就是原Thing 0被销毁时的输出——只是它的id已经被临时对象覆盖了。

2. 是否存在内存泄漏?

完全没有。容器的析构函数正确调用了delete[] this->things,这会自动销毁整个thing数组,包括数组里的两个对象(原Thing 0和Thing 1),所有通过new[]分配的内存都被正确释放了。

3. 是否需要手动销毁Thing 0?

不需要。你不需要手动销毁单个数组元素——delete[]会自动处理数组中所有对象的析构和内存释放。如果你尝试手动销毁c.at(0)对应的对象,反而会导致重复释放内存,引发未定义行为。

额外解释:为什么Thing 2被销毁两次?

  • 第一次:临时对象thing()创建后,完成赋值操作就会被销毁(临时对象的生命周期只到当前语句结束),所以打印Thing 2 destroyed。
  • 第二次:原Thing 0被赋值后id变成2,容器销毁时它被销毁,再次打印Thing 2 destroyed。

如果你想验证原Thing 0确实被修改了,可以给thing类加一个赋值运算符重载,打印赋值过程:

thing& operator=(const thing& other) {
    printf("Thing %zd assigned to Thing %zd\n", other.id, this->id);
    this->id = other.id;
    return *this;
}

加上后你会看到输出里多一行:Thing 2 assigned to Thing 0,就能直观看到赋值过程了。


内容的提问来源于stack exchange,提问作者sanitizedUser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 12:58:13