Pages

Monday, December 28, 2015

Move Semantics and Constructors

C++11 includes four types of constructors:
  1. Default Constructor
  2. Conversion Constructor (disabled if explicit)
  3. Copy Constructor (const &)
  4. Move Constructor (&&)
C++11 also allows two types of assignment operators:
  1. (Copy) Assignment Operator (const &)
  2. Move Assignment Operator (&&)
The following is the sample code to demonstrate what they look like:

// MyCPP11Container.cpp

template<typename T, int value>
class MyCPP11Container
{
public:
 MyCPP11Container() {                                  // 1. DEFAULT CTOR
  /*intended to be empty*/
 }
 explicit MyCPP11Container(int) : MyCPP11Container() {  // 2. Disable CONVERSION CTOR
                            // DELEGATE CONSTRUCTION
  m_pData = new T(value);
 }
 MyCPP11Container(const MyCPP11Container& other) : m_pData(NULL) { // 3. COPY CTOR
  *this = other;
 }
 MyCPP11Container(MyCPP11Container&& other) : m_pData(NULL) {      // 4. MOVE CTOR
  *this = std::move(other);
 }
 virtual ~MyCPP11Container() { // DESTRUCTOR
                if (m_pData != NULL) {
      delete m_pData;
                }
 }

 MyCPP11Container& operator=(const MyCPP11Container& other) { // ASSIGNMENT OPTR
  if (this == &other) {
   return *this;
  }
  delete m_pData;
  m_pData = new int(*(other.m_pData));
 }

 MyCPP11Container& operator=(MyCPP11Container&& other) {      // MOVE ASSIGNMENT OPTR
  if (this == &other) {
   return *this;
  }
  delete m_pData;
  m_pData = other.m_pData;
  other.m_Ptr = nullptr; // So the destructor doesn't free memory multiple times.
 }

 operator T() const { return *m_pData; } // type conversion: (T).

private:
 T* m_pData;
};


// C++11 version of swap in <utility> behaves like this:

template <class T> void swap (T& a, T& b) {                 // moved in <utility>
  T c(std::move(a)); a=std::move(b); b=std::move(c);
}

Note that swap() has been in <algorithm> until C++11. std::move() in <utility> is the new semantic move, which is different from the ranged std::move() in <algorithm>.

typename remove_reference<T>::type&& move (T&& arg) noexcept;  // <utility>



No comments:

Post a Comment