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.
No move constructor is automatically generated.
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.
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.
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.
A move constructor is called:
std::move(something)
std::forward<T>(something)
and T
is not an lvalue reference type (useful in template programming for "perfect forwarding")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&&) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With