1

我正在尝试为我的类 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 也发生了变化。我认为复制构造函数应该防止这种情况发生,但我无法弄清楚我在代码中做错了什么。

4

2 回答 2

4

std::list是一个指针列表。
您的复制构造函数执行这些指针的浅拷贝。在复制构造函数调用两者之后,a1a2是其元素指向相同对象的列表。
如果你想避免这种情况,要么:

  1. 只需在成员中存储对象而不是指针std::list
  2. 您的复制构造函数应该执行深度复制

将一个指针分配给另一个指针执行浅拷贝。简单来说,赋值后两个指针都指向同一个对象。您的代码大致相当于

#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
于 2013-03-08T03:23:33.240 回答
2

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

list<B> mylist;

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

于 2013-03-08T03:28:24.307 回答