#include <iostream>
#include <algorithm>
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!
Comments
0 B
|0 👍
/0 👎
0 B
|0 👍
/0 👎