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

Dan*_*ook 16 c++ dry copy-constructor assignment-operator

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

sel*_*tze 17

编写自定义复制构造函数和赋值运算符并不是"通用方法",它们适用于所有情况.但是有一种叫做"复制 - 交换"的成语:

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

    void swap(myclass & with);

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

    ...
};
Run Code Online (Sandbox Code Playgroud)

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

  • +1 - 我认为复制交换的好的和简洁的总结.关于重用存储也是个好主意. (2认同)
  • 你可能想指出你的operator =和更标准的const myclass&operator =(const myclass&other)之间的微妙之处; (2认同)

Vij*_*hew 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;
}
Run Code Online (Sandbox Code Playgroud)

  • 但遗憾的是复制构造函数不能使用成员初始化器,这样...... (4认同)
  • 内存泄漏!MakeDeepCopy忽略名称已指向已分配内存的可能性. (3认同)
  • 请注意,`t2 = t2`不能与赋值运算符一起使用.(例如,如果你想对它们的数组进行排序,你就会关心它.) (2认同)
  • 添加一点:我不认为重用是适用的.创建新对象与分配新对象之间存在差异.在简单的成员分配足够的情况下,不需要自定义拷贝构造函数和赋值运算符.如果你必须做更高级的事情(即管理分配的内存),复制和赋值之间的相似性接近于零. (2认同)
  • @Vijay:但是现在你忘了为拷贝构造初始化"name",这证明了我的观点.当涉及显式资源管理时,复制构造和复制分配会做不同的事情.重用的可能性很小. (2认同)
  • 先生,我不太明白,但是你的operator=没有返回任何东西,是吗? (2认同)

dav*_*420 6

My &My::operator = (My temp)  // thanks, sellibitze
{
    swap (*this, temp);
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

并实施专业化std::swap<> (My &, My &).

  • 正如Dave所说,alexandrescu已经发现了大约6年前的情况:http://www.ddj.com/cpp/184403855.有趣的读也是! (3认同)