我有一个看起来像的班级
I have a class looking like
class A{ double a, b, c, d, e; float af, bf, cf, df, ef; std::vector<double> av, bv, cv, dv, ev; std::vector<std::vector<double>> avv, bvv, cvv, dvv, evv; A(){} A(/*init values*/){/*Initialize all the values above using the input values*/} ~A(){} }现在我想实现一个赋值运算符,这样我就可以(在第二堂课中):
Now I would like to implement an assignment operator, such that I can do (in a second class):
class B{ private: A ac, bc, dc; public: B(/*init values*/) { ac = A(/*init values*/); bc = A(/*init values*/); dc = A(/*init values*/); } ~B(){} }我知道我可以遵循什么是copy-and-swap惯用法?和基本规则是什么?运算符重载的习惯用法?并实现
I know that I can follow What is the copy-and-swap idiom? and What are the basic rules and idioms for operator overloading? and implement
A& A::operator=(A rhs) { swap(rhs); return *this; }和相应的swap功能:
friend void swap(A& first, A& second) { using std::swap; swap(/*for each element*/); }对所有元素执行此操作很容易忘记一个元素,从而导致代码错误.将来的扩展也是如此,即在类头中添加变量,而不是在swap函数中添加变量.有没有更简单的方法可以做到这一点?
Doing so for all the elements is prone for forgetting one element, resulting in errors in the code. The same goes for extensions in the future, i.e. adding variables in the class header, but not in the swap function. Is there an easier way for doing that?
推荐答案您可以将所有数据成员放在一个集合中,而不必声明任何构造函数,赋值运算符和析构函数.您将获得默认的move/copy构造函数/赋值和聚合初始化的好处(如果直接进行初始化可能会有所帮助):
You could put all data member's in an aggregate, and just do not declare any constructor, assignment operator and destructor. You will get the benefits of the default move/copy constructor/assignment and aggregate initialization (which may help you if initialization is straight forward):
struct A{ double a, b, c, d, e; float af, bf, cf, df, ef; std::vector<double> av, bv, cv, dv, ev; std::vector<std::vector<double>> avv, bvv, cvv, dvv, evv; }; void swap(A& a,A& b){ a=std::exchange(b,a); }如果您必须维护一些不变式,则在内部结构中声明数据可能会有所帮助:
If you have to maintain some invariants, it may be helpfull to declare the data in an inner structure:
class A{ struct data_t{ double a, b, c, d, e; float af, bf, cf, df, ef; std::vector<double> av, bv, cv, dv, ev; std::vector<std::vector<double>> avv, bvv, cvv, dvv, evv; }; data_t data; //[...] void swap(A& other){ data = std::exchange(other.data,data); } };