简体   繁体   English

初始化器列表:复制构造函数和赋值运算符=冗余?

[英]Initializer lists: copy constructors and assignment operators = redundancy?

It seems that initalizer lists are a good idea for your class constructors and, I'm assuming, for the copy constructor as well. 似乎initalizer列表对于类构造函数来说是一个好主意 ,而且我假设,对于复制构造函数也是如此。 For the assignment operator one has to assign each member in the body of the function. 对于赋值运算符,必​​须在函数体中分配每个成员。 Consider the following simple block: 考虑以下简单块:

class Foo {
private: 
  int a,b;
public:
  Foo(int c, int d)  : a(c), b(d) {}
  Foo(const Foo & X) : a(X.a), b(X.b) {}
  Foo& operator=(const Foo& X) {
    if (this == &X) return *this;
    a = X.a;
    b = X.b;
    return *this;
  }
};

If a class has a moderate amount of data members, there are three places where one can mess up the the different assignments/initialization. 如果一个类有适量的数据成员,那么有三个地方可以搞乱不同的分配/初始化。 By that I mean, what if the copy constructor looked like: 我的意思是,如果复制构造函数看起来像:

  Foo(const Foo & X) : a(X.a), b(X.a) {}

or a line was missing from the operator=. 或者运营商缺少一条线=。 Since the assignment operator and the copy constructor often have the same effect (in that we copy members from one Foo to another) can I "reuse" the code from the copy constructor or the assignment operator or vice versa? 由于赋值运算符和复制构造函数通常具有相同的效果(因为我们将成员从一个Foo复制到另一个Foo),我可以“重用”复制构造函数或赋值运算符中的代码,反之亦然吗?

Your goal should be to not write copy constructors/assignment operators at all. 您的目标应该是不要编写复制构造函数/赋值运算符。 Your goal should be to let the compiler do it. 你的目标应该是让编译器去做。 Standard library containers are all copyable, so use them where reasonable. 标准库容器都是可复制的,因此在合理的情况下使用它们。

If there are members that cannot be copied correctly, then use smart pointers or other RAII objects. 如果有成员无法正确复制,则使用智能指针或其他RAII对象。 Those objects are the ones that should need special copy constructors/assignments. 那些对象是需要特殊拷贝构造函数/赋值的对象。 And they only need them for their one member. 他们只需要他们的一个成员。

Everything else should not use them. 其他一切都不应该使用它们。

Since the assignment operator and the copy constructor often have the same effect. 由于赋值运算符和复制构造函数通常具有相同的效果。

Not at all, one does initialization while the other does assignment. 完全没有,一个做初始化而另一个做分配。 They are different in the initial state of the object, and their tasks are separate (though similar). 它们在对象的初始状态不同,它们的任务是分开的(虽然相似)。 The canonical assignment operator is usually done as: 规范赋值运算符通常用于:

Foo& operator=(Foo right) {
    right.swap( *this );
    return *this;
}

It might not be valid to forward all to an assignment operator, but that is was commmon in C++03 where it was allowed. 将all转发给赋值运算符可能无效,但这是允许的C ++ 03中的commmon。

In C++11 constructors are easier: forward all the constructors to one master constructor. 在C ++ 11中,构造函数更容易:将所有构造函数转发给一个主构造函数。

class Foo {
private: 
  int a,b;
public:
  Foo(int c, int d)  : a(c), b(d) {}
  Foo(const Foo & X) : Foo(x.a, x.d) {} 
  //syntax may be wrong, I don't have a C++11 compiler
  Foo& operator=(const Foo& X) {
    if (this == &X) return *this;
    a = X.a;
    b = X.b;
    return *this;
  }
}

In C++03 (where it is allowed) 在C ++ 03中(允许)

class Foo {
private: 
  int a,b;
  void init(int c, int d) {a=c; b=d;}
public:
  Foo(int c, int d)  : {init(c,d);}
  Foo(const Foo & X) : {init(X.a, X.b);} 
  Foo& operator=(const Foo& X) { init(X.a, X.b);} 
}

But keep in mind that this cannot be used in some common cases. 但请记住,这不能用于某些常见情况。 (any object that isn't assignable) (任何不可分配的对象)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM