减少operator =和复制构造函数之间的代码重复

时间:2009-09-25 12:57:32

标签: c++ dry copy-constructor assignment-operator

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

4 个答案:

答案 0 :(得分:17)

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

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

    void swap(myclass & with);

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

    ...
};

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

答案 1 :(得分:16)

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

#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;
}

答案 2 :(得分:6)

My &My::operator = (My temp)  // thanks, sellibitze
{
    swap (*this, temp);
    return *this;
}

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

答案 3 :(得分:3)

正如已经有很多海报所指出的那样,拥有operator =创建一个新的 具有复制构造函数的对象然后使用swap是用于不必在operator =中复制代码的常用技术。

那就是说,我想指出一些这种技术的专业知识,以帮助您确定它是否合适。

Pro - 例外安全

如果您的对象具有可能导致抛出的资源需求并假设交换不会抛出,则此技术提供了异常安全的强有力保证(被分配的对象具有另一个对象的值,或者它是不变)。

资源足迹

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