Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When Does Move Constructor get called?

I'm confused about when a move constructor gets called vs a copy constructor. I've read the following sources:

Move constructor is not getting called in C++0x

Move semantics and rvalue references in C++11

msdn

All of these sources are either overcomplicated(I just want a simple example) or only show how to write a move constructor, but not how to call it. Ive written a simple problem to be more specific:

const class noConstruct{}NoConstruct; class a { private:     int *Array; public:     a();     a(noConstruct);     a(const a&);     a& operator=(const a&);     a(a&&);     a& operator=(a&&);     ~a(); };  a::a() {     Array=new int[5]{1,2,3,4,5}; } a::a(noConstruct Parameter) {     Array=nullptr; } a::a(const a& Old): Array(Old.Array) {  } a& a::operator=(const a&Old) {     delete[] Array;     Array=new int[5];     for (int i=0;i!=5;i++)     {         Array[i]=Old.Array[i];     }     return *this; } a::a(a&&Old) {     Array=Old.Array;     Old.Array=nullptr; } a& a::operator=(a&&Old) {     Array=Old.Array;     Old.Array=nullptr;     return *this; } a::~a() {     delete[] Array; }  int main() {     a A(NoConstruct),B(NoConstruct),C;     A=C;     B=C; } 

currently A,B,and C all have different pointer values. I would like A to have a new pointer, B to have C's old pointer, and C to have a null pointer.

somewhat off topic, but If one could suggest a documentation where i could learn about these new features in detail i would be grateful and would probably not need to ask many more questions.

like image 769
Lauer Avatar asked Oct 29 '12 16:10

Lauer


People also ask

Is move constructor automatically generated?

No move constructor is automatically generated.

How does move constructor work?

Move constructor moves the resources in the heap, i.e., unlike copy constructors which copy the data of the existing object and assigning it to the new object move constructor just makes the pointer of the declared object to point to the data of temporary object and nulls out the pointer of the temporary objects.

When move assignment is called?

The move assignment operator is called whenever it is selected by overload resolution, e.g. when an object appears on the left-hand side of an assignment expression, where the right-hand side is an rvalue of the same or implicitly convertible type.

What is the difference between move constructor and copy constructor?

If any constructor is being called, it means a new object is being created in memory. So, the only difference between a copy constructor and a move constructor is whether the source object that is passed to the constructor will have its member fields copied or moved into the new object.


1 Answers

A move constructor is called:

  • when an object initializer is std::move(something)
  • when an object initializer is std::forward<T>(something) and T is not an lvalue reference type (useful in template programming for "perfect forwarding")
  • when an object initializer is a temporary and the compiler doesn't eliminate the copy/move entirely
  • when returning a function-local class object by value and the compiler doesn't eliminate the copy/move entirely
  • when throwing a function-local class object and the compiler doesn't eliminate the copy/move entirely

This is not a complete list. Note that an "object initializer" can be a function argument, if the parameter has a class type (not reference).

a RetByValue() {     a obj;     return obj; // Might call move ctor, or no ctor. }  void TakeByValue(a);  int main() {     a a1;     a a2 = a1; // copy ctor     a a3 = std::move(a1); // move ctor      TakeByValue(std::move(a2)); // Might call move ctor, or no ctor.      a a4 = RetByValue(); // Might call move ctor, or no ctor.      a1 = RetByValue(); // Calls move assignment, a::operator=(a&&) } 
like image 52
aschepler Avatar answered Oct 17 '22 09:10

aschepler