18

我有一个需要非默认复制构造函数和赋值运算符的类(它包含指针列表)。有没有什么通用的方法可以减少复制构造函数和赋值运算符之间的代码重复?

4

4 回答 4

18

没有“通用方法”来编写适用于所有情况的自定义复制构造函数和赋值运算符。但是有一个成语叫做“copy-&-swap”:

 class myclass
 {
    ...
 public:
    myclass(myclass const&);

    void swap(myclass & with);

    myclass& operator=(myclass copy) {
        this->swap(copy);
        return *this;
    }

    ...
};

它在许多(但不是全部)情况下都很有用。有时你可以做得更好。向量或字符串可以有更好的分配,如果它足够大,它可以重用分配的存储。

于 2009-09-25T13:04:34.213 回答
17

将公共代码分解为私有成员函数。一个简单(相当人为)的例子:

#include <iostream>

class Test
{
public:
  Test(const char* n)
  {
    name = new char[20];
    strcpy(name, n);
  }

  ~Test()
  {
    delete[] name;
  }

  // Copy constructor
  Test(const Test& t)
  {
    std::cout << "In copy constructor.\n";
    MakeDeepCopy(t);
  }

  // Assignment operator
  const Test& operator=(const Test& t)
  {
    std::cout << "In assignment operator.\n";
    MakeDeepCopy(t);
  }

  const char* get_name() const { return name; }

private:
  // Common function where the actual copying happens.
  void MakeDeepCopy(const Test& t)
  {        
    strcpy(name, t.name);
  }

private:
  char* name;
};

int
main()
{
  Test t("vijay");
  Test t2(t); // Calls copy constructor.
  Test t3(""); 
  t3 = t2; // Calls the assignment operator.

  std::cout << t.get_name() << ", " << t2.get_name() << ", " << t3.get_name() << '\n';

  return 0;
}
于 2009-09-25T13:01:32.517 回答
8
My &My::operator = (My temp)  // thanks, sellibitze
{
    swap (*this, temp);
    return *this;
}

并实施专门的std::swap<> (My &, My &).

于 2009-09-25T13:05:04.553 回答
3

正如很多张贴者已经指出的那样,让 operator= 使用复制构造函数创建一个新对象,然后使用交换是不必在 operator= 中复制代码的常用技术。

也就是说,我想指出这种技术的一些优点和缺点,以帮助您确定它是否合适。

Pro - 异常安全

如果您的对象具有可能导致抛出的资源需求并假设交换不会抛出,则此技术提供了异常安全性的强有力保证(被分配给的对象已采用其他对象的值或未更改)。

控制资源足迹

这种技术的一个问题是它需要在旧对象发布之前创建一个完整的新对象。如果您的对象需要大量资源,这可能是个问题。

于 2009-09-25T20:59:08.547 回答