Tips of Rule of Five

Example

class Customer {
public:
   Customer() = default;

   // copy constructor
   Customer(const Customer& rhs)
   // note that the construction order is the same as the declaration order
   // but not the order in initializer list
   : values{rhs.values}, name{rhs.name}
   { }

   // move constructor
   Customer(Customer&& rhs) noexcept
   : values{std::move(rhs.values)}, name{std::move(rhs.name)}
   { }

   // copy assignment
   // Using ref-qualifier to ensure that only lvalue can call assignment
   Customer& operator=(const Customer& rhs) &
   {
      // if all members are STL, checking self-copy is redundant
      if (&rhs == this) return *this;
      values = rhs.values;
      name = rhs.name;
      return *this;
   }
   // Or, using copy-and-swap idiom
   Customer& operator=(Customer rhs) &
   {
       std::swap(*this, rhs);
       return *this;
   }

   // move assignment
   // Using ref-qualifier to ensure that only lvalue can call assignment
   Customer& operator=(Customer&& rhs) & noexcept
   {
      if (&rhs == this) return *this;
      values = std::move(rhs.values);
      name = std::move(rhs.name);
      return *this;
   }

private:
   std::string name;
   std::vector<int> values;
};

Tips