C++浅拷贝疑惑:栈类对象拷贝后弹栈状态未共享
浅拷贝栈类后弹栈结果不符合预期的原因分析
问题核心:你误以为浅拷贝会让两个对象共享所有状态,但实际上C++默认的浅拷贝是成员变量逐值复制:
- 底层数组指针
arr会被拷贝,所以对象a和b确实共享同一块数组内存 - 但栈顶索引(比如
top,用来记录当前栈顶位置的int变量)是值类型,浅拷贝后a和b各自拥有独立的top变量,修改其中一个的top不会影响另一个
- 底层数组指针
还原你的执行流程(假设栈顶索引从-1开始,压栈时先自增再赋值):
- 对象a压入1、2后,
top的值为1(指向数组中存储2的位置) - 浅拷贝得到对象b,此时b的
arr和a指向同一数组,b的top也被复制为1 - 调用
b.depile():b的top自减为0,但数组里的元素2并未被删除,a的top依然保持1不变 - 调用
a.depile():a的top自减为0,弹出的是数组索引1处的元素2,最终输出两个2
- 对象a压入1、2后,
验证方法:在
depile()函数中添加一行打印当前对象的top值,就能直观看到a和b的top是各自独立变化的。常见修正方向:
- 如果想让两个对象真正共享栈的完整状态(包括栈顶位置),需要把
top也放到堆内存中,让a和b的指针指向同一个top变量,但这种设计不符合栈的常规使用场景,容易引发逻辑混乱 - 栈类通常应该实现深拷贝,让每个对象拥有独立的数组和状态,避免共享内存导致的意外问题。示例深拷贝构造函数如下:
pile_entier(const pile_entier& other) { capacity = other.capacity; top = other.top; arr = new int[capacity]; // 逐元素复制数组内容 for (int i = 0; i <= top; ++i) { arr[i] = other.arr[i]; } } - 或者直接禁用拷贝构造和拷贝赋值运算符,强制用户使用移动语义、指针或引用来操作对象:
pile_entier(const pile_entier&) = delete; pile_entier& operator=(const pile_entier&) = delete;
- 如果想让两个对象真正共享栈的完整状态(包括栈顶位置),需要把
内容的提问来源于stack exchange,提问作者ILYASS LIRMAQUI
相关产品推荐
相关产品推荐

