Implement assignment operator for class with large

2019-07-29 18:52发布

问题:

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(){}
}

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

and the respective swap-function:

friend void swap(A& first, A& second)
{
    using std::swap;

    swap(/*for each element*/);
}

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?

回答1:

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