Reputation: 127
I have the following code (http://coliru.stacked-crooked.com/a/a0e5ff6ee73634ee):
#include <iostream
class A {
public:
explicit A(int a) {std::cout << "Main constructor" << std::endl;}
A(const A& a) {std::cout << "Copy constructor" << std::endl;}
A& operator =(const A& a) {std::cout << "Copy assignment" << std::endl; return *this;}
A(A&& a) {std::cout << "Move constructor" << std::endl;}
A& operator =(A&& a) {std::cout << "Move assignemnt" << std::endl; return *this;}
};
int main(void) {
std::cout << "\nA a3(A(0))" << std::endl;
A a3(A(0));
std::cout << "\nA a31(std::move(A(0)))" << std::endl;
A a31(std::move(A(0)));
std::cout << "\nA a4(*(new A(0)))" << std::endl;
A a4(*(new A(0)));
std::cout << "\nA a41(std::move(*(new A(0))))" << std::endl;
A a41(std::move(*(new A(0))));
}
This code writes the following:
A a3(A(0))
Main constructor
-> After having read Move semantics and copy constructor I assume RVO happened and a3 takes over the content of the construction of A(0).
A a31(std::move(A(0)))
Main constructor
Move constructor
-> OK
A a4(*(new A(0)))
Main constructor
Copy constructor
-> Why is not this a move constructor instead of the Copy constructor ?
A a41(std::move(*(new A(0))))
Main constructor
Move constructor
-> OK
EDIT:
After analyzing the problem a little deeper I realized that actually @sameerkn is right. However as @Angew suggested I tried to analyze what is happening with a static variable: such variables are not moved as one could expect (they seem to be treated as const variables).
See here full code:
http://melpon.org/wandbox/permlink/RCntHB9dcefv93ID
Following code:
A a1(testStatic(1));
A a2(std::move(*(a1.getPointer()))); <-- Moving a dereference
std::cout << "\na1.mValue = " << a1.mValue << std::endl;
std::cout << "a2.mValue = " << a2.mValue << std::endl;
Will return:
Main constructor: This is my long String that should not be SSOed [STATIC]
Copy constructor: This is my long String that should not be SSOed [STATIC]
return aLocal
Move constructor <-- The dereferenced pointer is moved as expected
Destructor: [mValue moved away] <-- See here that the string was moved away
Move constructor <-- Moved again because of std::move
Upvotes: 2
Views: 840
Reputation: 2259
new A(0);
Creating an object via "new". (NOTE: Its creating a pure object which has an identity which can be identified by the address returned by "new" in code and this object is available to rest to the code for its utilization and in no sense a temporary nameless object.)
And move semantic work on purely temporary object whose identity is not available for utilization.
Upvotes: 1
Reputation: 171127
A a4(*(new A(0))) Main constructor Copy constructor
-> Why is not this a move constructor instead of the Copy constructor ?
Because dereferencing a pointer gives an lvalue reference. The fact that the pointer itself is an rvalue plays no role—and why should it? You can very easily have an rvalue pointer pointing to something that is most definitely not an rvalue. Example:
std::string s{"42"};
std::string* getPointer()
{
return &s;
}
int main()
{
std::string x(*getPointer());
std::cout << s;
}
The pointer returned by getPointer
is an rvalue, just as the pointer returned by new A
. But you certainly would not expect the code to move the contents of s
into x
, would you?
Upvotes: 8