#include #include class Leon { public: int* data = nullptr; //default member initialization int length = 0; //default construction (container-friendly!) Leon() {} //custom construction. Single argument constructor should always be explicit! explicit Leon(int length) : data(new int[length]), length(length){ } //copy construction Leon(const Leon& other) : data(new int[other.length]), length(other.length) { std::copy(other.data, other.data + other.length, data); } //move constructor Leon(Leon&& other) { data = other.data; length = other.length; other.data = nullptr; other.length = 0; } //copy-assignment Leon& operator= (const Leon& other) { if (&other == this) { return *this; } if (nullptr != data) { delete[] data; } length = other.length; data = new int[other.length]; std::copy(other.data, other.data + other.length, data); return *this; } Leon& operator= (Leon&& other){ std::swap(other.length, length); std::swap(other.data, data); return *this; } ~Leon() { if (nullptr != data){ delete[] data; } } }; //argument by copy, return value by copy. Potentially large objects, expensive! Leon doSomethingExpensive(Leon p_leon) { return p_leon; //will copy (expensive!) but *can* move, if available! (RVO almost always saves us though) } int main(int argc, int* argv[]){ Leon a; //default constructible == container support Leon b(10); //custom construction (explicit!) Leon c(b); //copy construction Leon d(20); d = b; //copy assignment (remember to clean out the content of d!) d = doSomethingExpensive(b); //b is an lvalue (named!) so it will be copied to the argument d = doSomethingExpensive(Leon(50)); //Leon is an rvalue (no name!), and will *move* to the argument if the move constructor exist d = std::move(b); //move-assign - give d the content of b, if move assignment operator exists. // b is left valid but undefined (don't use after move!) return 0; } //Here is an ideal implementation of the big five: // https://stackoverflow.com/a/12653520 // notice how beautifully short and compact the boiler plate can be. :) // especially this neat hack: instead of writing two assignment operators, // you could write just one that takes its argument by value. That one can // be used for both copy and move assignment!