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

为何C++中vector.erase()行为不符合预期?

关于vector::erase的析构函数调用疑惑

我写了个测试vector::erase特性的程序,定义了MyClass0类,构造和析构时会打印信息。接着创建了包含4个MyClass0对象的vector,执行vec0.erase(vec0.begin() + 1)删除第二个元素时,我预期输出GoodBye From 2,但实际输出的是GoodBye From 4,看起来vector第四个元素的析构函数被提前调用了(它本该在main结束时才析构)。

测试代码

#include <iostream>
#include <vector>

using std::cout;
using std::endl;

class MyClass0
{
public:
    MyClass0(int i_i_) : i_(i_i_)
    {
        cout << "Hello From " << this->i_ << endl;
    }
    ~MyClass0()
    {
        cout << "GoodBye From " << this->i_ << endl;
    }
    std::string MyToString()
    {
        return std::string("This is ") + std::to_string(this->i_);
    }
private:
    int i_;
};


int main()
{
    std::vector<MyClass0> vec0 = { MyClass0(1), MyClass0(2), MyClass0(3), MyClass0(4) };
    cout << endl << "Before erasing..." << endl;
    vec0.erase(vec0.begin() + 1);
    cout << "After erase" << endl << endl;

    return 0;
}

运行输出

Hello From 1
Hello From 2
Hello From 3
Hello From 4
GoodBye From 4
GoodBye From 3
GoodBye From 2
GoodBye From 1

Before erasing...
GoodBye From 4
After erase

GoodBye From 1
GoodBye From 3
GoodBye From 4

问题原因解析

  1. 初始化阶段的临时对象析构:
    用初始化列表{MyClass0(1), ...}创建vector时,会先构造4个临时MyClass0对象(对应输出里的前4个Hello From),随后vector会把这些临时对象拷贝到自己的内部存储中,临时对象完成使命后被依次析构(对应输出里的GoodBye From 4、3、2、1)。此时vector内部存储的是4个拷贝后的对象,i_值分别为1、2、3、4。

  2. erase操作的元素移动与析构:
    执行erase(vec0.begin()+1)删除第二个元素时,vector会将删除位置之后的元素(第三个、第四个)依次向前移动一个位置,来填补被删除的空缺:

    • 第三个元素(i_=3)移动到第二个位置
    • 第四个元素(i_=4)移动到第三个位置
      移动完成后,vector的大小从4减为3,原来的第四个位置的对象就变成了多余的,会被析构。由于你的MyClass0没有自定义移动/拷贝构造函数,编译器生成的默认版本只会简单复制i_的值,所以这个被析构的对象的i_还是4,因此输出GoodBye From 4。
      而你预期的第二个元素(i_=2),其实已经被第三个元素覆盖了——它的析构是在被移动操作覆盖时发生的,但因为没有自定义拷贝/移动构造,你看不到这个过程的输出,只能看到最后多余元素的析构。
  3. main结束时的vector对象析构:
    main函数结束时,vector中剩下的三个对象(i_=1、3、4)会被依次析构,对应输出最后的三行GoodBye From。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 22:46:03