#include using namespace std; class tellme { public: tellme(int i=0) { cout << "normal constructor: " << i << endl; v = i; } ~tellme() { cout << "destructor: " << v << endl; } tellme(const tellme &t) { cout << "copy constructor: " << t.v << endl; v = t.v; } #ifdef CPP11 tellme(tellme &&t) { cout << "move constructor: " << t.v << endl; v = t.v; t.v = -1; } #endif tellme &operator=(const tellme &t) { if (&t != this) { cout << "copy assignment: " << t.v << endl; v = t.v; } return *this; } #ifdef CPP11 tellme &operator=(tellme &&t) { // don't need to test for ==this, as // C++11 states such behavior is "undefined" -- but you may cout << "move assignment: " << t.v << endl; v = t.v; t.v = -1; } #endif int v; }; tellme tellfactory(int i) { // don't do "return tellme(i)" as C++ allows for return type optimization tellme ret; for(;i>0;i--) ret.v++; return ret; } #ifdef CPP11 tellme &&fac(int i) { // nevermind how we'll recover the memory... return std::move(*(new tellme(i))); } #endif int main(int argc, char **argv) { cout << "----making a: " << endl; tellme a(1); // make an object cout << "----making b: " << endl; tellme b(a); // copy that object; cout << "----making c: " << endl; tellme c(tellfactory(2)); // make an object, and return it cout << "----making d: " << endl; tellme d = tellfactory(3); // make an object, and return it cout << "----making e: " << endl; tellme e; e = tellfactory(4); // return is (p)rvalue: can use move cout << "----making f: " << endl; tellme f; f = e; // e is an lvalue: must use copy #ifdef CPP11 cout << "----making g: " << endl; tellme g; g = std::move(f); // this will only be a good idea if we never // want to use f again cout << "----making h: " << endl; tellme h(fac(5)); // this should be a move // fac(5) is an xvalue: it has a name, but can be moved // [it has a name because fac(5)=tellme(3); is a valid stmt] cout << "----making i,j,k: " << endl; tellme &&i = fac(6); // fac(6) is an xvalue // but i is an lvalue tellme j(i); // these need to be copied (not moved) tellme k(i); tellme &l = i; // this is fine. -- consider it. // by binding fac(6) to i, I've extended its lifetime and it // is now an lvalue. #endif cout << "==================" << endl; }