c++复制构造函数:带有指针列表的字段

C++ copy constructor: field with list of pointers

本文关键字:指针 列表 字段 复制 构造函数 c++      更新时间:2023-10-16

我试图为我的类a创建一个复制构造函数,其中包含类型b的指针列表。我试图这样做的方式如下:

class A
{
 private:
   list<B*> myList;
   list<B*>::iterator iter;
public:
  A()
  {
   }
 // Copy constructor
 A(const A &src)
  {
    myList.assign(src.myList.begin(), src.myList.end());
  }
A& operator= (const A &src);
 };
A& A::operator= (const A &src)
{
// do the copy
myList.assign(src.myList.begin(), src.myList.end());
// return the existing object
return *this;
}

现在,我的问题是如果我这样做:

A=a1;
//call function that will change a1
A  a2(a1);
//call function that will change a1

然后在调用最后一个改变a1的函数之后,我注意到a2也发生了变化。我认为复制构造函数应该防止这种情况发生,但我不知道我在代码中做错了什么。

您的std::list是一个指针列表。
复制构造函数对这些指针执行浅层复制。在复制构造函数调用之后,a1a2都是元素指向相同对象的列表。
如果您想避免这种情况,可以:

  1. std::list成员或
  2. 中存储对象而不是指针
  3. 你的复制构造函数应该执行一个深度复制

将一个指针赋值给另一个指针执行浅复制。简单地说,赋值之后,两个指针都指向同一个对象。您的代码大致相当于:

#include<iostream>
using namespace std;
int main()
{
    int i = 10;
    int *ptr = &i;
    int *ptr2 = ptr;
    std::cout<<"ni = "<<i;
    std::cout<<"n*ptr = "<<*ptr;
    std::cout<<"n*ptr2 = "<<*ptr2;
    *ptr2 = 20;
    std::cout<<"ni = "<<i;
    std::cout<<"n*ptr = "<<*ptr;
    std::cout<<"n*ptr2 = "<<*ptr2;
    return 0;
}
输出:

i = 10
*ptr = 10
*ptr2 = 10
i = 20
*ptr = 20
*ptr2 = 20

您当前的复制构造函数实际上等同于如果您自己不实现的话将自动生成的复制构造函数:它复制列表的所有元素,即指针。如果复制一个列表对象并对原始对象进行更改(例如添加或删除元素),则这些更改不会反映在副本中。但是对存储在列表中的对象的更改将在副本中反映出来,因为列表只存储指向它们的指针。如果您不想要这种行为,则必须在列表中存储实际的B对象:

list<B> mylist;

当然这意味着B必须是可复制的