#include #include #include "example-sub.h" using namespace std; int Example::nMoveConstructors = 0; int Example::nCopyConstructors = 0; int Example::nMoveAssigns = 0; int Example::nCopyAssigns = 0; Example::Example(const char* str) { cout << "Constructing " << str << endl; nameStr = strdup(str); } // Copy constructor Example::Example(const Example &other) { cout << "Copy constructing from " << other.name() << endl; nCopyConstructors++; nameStr = strdup("copy constructed"); } // Copy assignment Example& Example::operator=(const Example &other) { cout << "Copy assignment from " << other.name() << " to " << name() << endl; nCopyAssigns++; // We have to be careful to handle self-assignments correctly: if ( &other == this ) return *this; if ( nameStr != nullptr ) free(nameStr); nameStr = strdup(other.nameStr); return *this; } Example::~Example() { cout << "Example destructor(" << name() << ")" << endl; free((void*)nameStr); } Example Example::exampleFunc(const Example ex) { static int invocationCount = 0; string label("exampleFuncLocalAndReturn "); label += std::to_string(invocationCount++); Example result(label.c_str()); return result; } #ifndef _USE_MOVE std::string Example::countString() { ostringstream result; result << "nCopyConstructors = " << nCopyConstructors << endl; result << "nCopyAssigns = " << nCopyAssigns << endl; return result.str(); } #endif // _USE_MOVE //-------------------------------------------------------------------------------- #ifdef _USE_MOVE // Move constructor Example::Example(Example &&other) noexcept { cout << "Move constructing from " << other.name() << " to " << name() << endl; nMoveConstructors++; // We steal ("move") the memory allocated by the other object, which is faster // than creating a new copy of it. nameStr = other.nameStr; other.nameStr = NULL; } // Move assignment Example& Example::operator=(Example &&other) noexcept { cout << "Move assignment: " << name() << " = " << other.name() << endl; nMoveAssigns++; // We have to be careful to handle self-assignments correctly: if ( &other == this ) return *this; if ( nameStr != nullptr ) free(nameStr); nameStr = other.nameStr; // We assign a literal to the other's name, for printing purposes. // Normally, we'd set other.nameStr to nullptr. other.nameStr = strdup("move assignment moved this name away"); return *this; } std::string Example::countString() { ostringstream result; result << "nMoveConstructors = " << nMoveConstructors << endl; result << "nCopyConstructors = " << nCopyConstructors << endl; result << "nMoveAssigns = " << nMoveAssigns << endl; result << "nCopyAssigns = " << nCopyAssigns << endl; return result.str(); } #endif // _USE_MOVE //--------------------------------------------------------------------------------