28

Move semantics in C++11

 5 years ago
source link: https://www.tuicool.com/articles/hit/Rb6f2mi
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

After studying an example for Move Semantics of C++11, I write a more complete code snippet:

#include <iostream>
 
using namespace std;
 
class Intvec {
  public:
    explicit Intvec(size_t num = 0)
      : m_size(num), m_data(new int[m_size]) {
      log("constructor");
    }
 
    ~Intvec() {
      log("destructor");
      if (m_data) {
        delete[] m_data;
        m_data = 0;
      }
    }
 
    Intvec(const Intvec& other) : m_size(other.m_size), m_data(new int[m_size]) {
      log("copy constructor");
      for (size_t i = 0; i < m_size; ++i)
        m_data[i] = other.m_data[i];
    }
 
    Intvec(Intvec&& other) {
      log("move constructor");
      std::swap(m_size, other.m_size);
      std::swap(m_data, other.m_data);
      other.m_size = 0;
      other.m_data = nullptr;
    }
 
    Intvec& operator=(const Intvec& other) {
      log("copy assignment operator");
      Intvec tmp(other);
      std::swap(m_size, tmp.m_size);
      std::swap(m_data, tmp.m_data);
      return *this;
    }
 
    Intvec& operator=(Intvec&& other) {
      log("move assignment operator");
      std::swap(m_size, other.m_size);
      std::swap(m_data, other.m_data);
      return *this;
    }
 
  private:
    void log(const char* msg) {
      cout << "[" << this << "] " << msg << "\n";
    }
 
    size_t m_size;
    int* m_data;
};
 
int main(void) {
  Intvec v1(20);
  Intvec v2;
 
  cout << "assigning lvalue...\n";
  v2 = v1;
  cout << "ended assigning lvalue...\n";
 
  //Intvec v4 = std::move(Intvec(30));
  Intvec v3;
  cout << "move assigning...\n";
  v3 = Intvec(30);
  cout << "ended move assigning...\n";
 
  cout << "move constructor\n";
  Intvec v4 = std::move(v3);
  cout << "ended move constructor\n";
 
  return 0;
}

Pay attention to last two lines in ‘move constructor’:

...
      other.m_size = 0;
      other.m_data = nullptr;
...

Since ‘move constructor’ will not set initial value for m_size and m_data of ‘v4’, the m_size and m_data of ‘v3’ will be uninitial after swaps. Adding the two lines of code means to initialize m_size and m_data of ‘v3’.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK