关于c ++:减少operator =和复制构造函数之间的代码重复

Reducing code duplication between operator= and the copy constructor

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


对于编写在所有情况下都有效的自定义复制构造函数和分配运算符,没有"常规方法"。但有一个成语叫做"复制-交换":

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 class myclass
 {
    ...
 public:
    myclass(myclass const&);

    void swap(myclass & with);

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

    ...
};

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#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.
"
;
    MakeDeepCopy(t);
  }

  // Assignment operator
  const Test& operator=(const Test& t)
  {
    std::cout <<"In assignment operator.
"
;
    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() << '
'
;

  return 0;
}


1
2
3
4
5
My &My::operator = (My temp)  // thanks, sellibitze
{
    swap (*this, temp);
    return *this;
}

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


正如许多海报所指出的,having operator=创建一个新的使用复制构造函数然后使用swap的对象是一种常用的技术,用于不必在operator=中复制代码。

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

例外安全

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

Con-资源足迹

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