mercredi 25 juillet 2018

Move semantics in C++11

I would like to fully understand move semantics in C++11. So I have written couple of classes to see when different constructors are called:

#include <iostream>
using namespace std;

class A {
public:
   A() : a1_(0) {std::cout << "Calling constructor" << std::endl;}
   A(A&& other){
      std::cout << "Calling move constructor" << std::endl;
      a1_ = other.a1_;
      other.a1_ = 0;
   }
   // Move assignment operator.
   A& operator=(A&& other) {
      std::cout << "Calling move operator" << std::endl;
      if (this != &other) {
         a1_ = other.a1_;
         other.a1_ = 0;
      }
      return *this;
   }
   // Copy constructor.
   A(const A& other) {
      std::cout << "Calling copy constructor" << std::endl;
      a1_ = other.a1_;
   }
   // Copy assignment operator.
   A& operator=(const A& other) {
      std::cout << "Calling copy assignment operator" << std::endl;
      if (this != &other) {
         a1_ = other.a1_;
      }
      return *this;
   }
   private:
      int a1_;
};

class B {
   A oA_;
   public:
       B() {}
       void setoA(A a) {oA_ = a;}
       A getoA() {return oA_;}
};
A createA() {
  A a1;
  return a1;
}
B createB() {
   B tmpB;
   A tmpA;
   tmpB.setoA(tmpA);
   return tmpB;
}

int main() {
   B b;
   A a;
   b.setoA(a);
   std::cout << "**************************" << std::endl;
   b.setoA(createA());
   std::cout << "**************************" << std::endl;
   b.setoA(std::move(createA()));
   std::cout << "**************************" << std::endl;
   B b2;
   b2.setoA(b.getoA());
   std::cout << "**************************" << std::endl;
   createB();
   return 0;
}

When I check the output of this code:

Calling constructor

Calling constructor

Calling copy constructor

Calling copy assignment operator

++++++++++++++++++++++++++++++++++

Calling constructor

Calling copy assignment operator

++++++++++++++++++++++++++++++++++

Calling constructor

Calling move constructor

Calling copy assignment operator

++++++++++++++++++++++++++++++++++

Calling constructor

Calling copy constructor

Calling copy assignment operator

++++++++++++++++++++++++++++++++++

Calling constructor

Calling constructor

Calling copy constructor

Calling copy assignment operator

I have several doubts here: First of all in first section, why is constructor being called twice?

I thought that if you pass r-value move constructor will be called, is that right? Isn't this b.setoA(createA()); an r-value?

Aucun commentaire:

Enregistrer un commentaire