How to actually implement the rule of five?

后端 未结 6 1153
遥遥无期
遥遥无期 2020-11-28 04:05

UPDATE at the bottom

q1: How would you implement the rule of five for a class that manages rather heavy resources, but of which you

6条回答
  •  广开言路
    2020-11-28 04:42

    You've missed a significant optimization in your copy assignment operator. And subsequently the situation has gotten confused.

      AnObject& operator = ( const AnObject& rh )
      {
        if (this != &rh)
        {
          if (n != rh.n)
          {
             delete [] a;
             n = 0;
             a = new int [ rh.n ];
             n = rh.n;
          }
          std::copy(rh.a, rh.a+n, a);
        }
        return *this;
      }
    

    Unless you really never think you'll be assigning AnObjects of the same size, this is much better. Never throw away resources if you can recycle them.

    Some might complain that the AnObject's copy assignment operator now has only basic exception safety instead of strong exception safety. However consider this:

    Your clients can always take a fast assignment operator and give it strong exception safety. But they can't take a slow assignment operator and make it faster.

    template 
    T&
    strong_assign(T& x, T y)
    {
        swap(x, y);
        return x;
    }
    

    Your move constructor is fine, but your move assignment operator has a memory leak. It should be:

      AnObject& operator = ( AnObject&& rh )
      {
        delete [] a;
        n = rh.n;
        a = rh.a;
        rh.n = 0;
        rh.a = nullptr;
        return *this;
      }
    

    ...

    Data a = MakeData();
    Data c = 5 * a + ( 1 + MakeMoreData() ) / 3;
    

    q2: Using a combination of copy elision / RVO / move semantics the compiler should be able to this this with a minimum of copying, no?

    You may need to overload your operators to take advantage of resources in rvalues:

    Data operator+(Data&& x, const Data& y)
    {
       // recycle resources in x!
       x += y;
       return std::move(x);
    }
    

    Ultimately resources ought to be created exactly once for each Data you care about. There should be no needless new/delete just for the purpose of moving things around.

提交回复
热议问题