I've been trying to nail down the rule of 5, but most of the information online is vastly over-complicated, and the example codes differ.
Even my textbook doesn't cover this topic very well.
On move semantics:
Templates, rvalues and lvalues aside, as I understand it, move semantics are simply this:
int other = 0; //Initial value
int number = 3; //Some data
int *pointer1 = &number; //Source pointer
int *pointer2 = &other; //Destination pointer
*pointer2 = *pointer1; //Both pointers now point to same data
pointer1 = nullptr; //Pointer2 now points to nothing
//The reference to 'data' has been 'moved' from pointer1 to pointer2
As apposed to copying, which would be the equivalent of something like this:
pointer1 = &number; //Reset pointer1
int newnumber = 0; //New address for the data
newnumber = *pointer1; //Address is assigned value
pointer2 = &newnumber; //Assign pointer to new address
//The data from pointer1 has been 'copied' to pointer2, at the address 'newnumber'
No explanation of rvalues, lvalues or templates is necessary, I would go as far as to say those topics are unrelated.
The fact that the first example is faster than the second, should be a given. And I would also point out that any efficient code prior to C++ 11 will do this.
To my understanding, the idea was to bundle all of this behavior in a neat little operator move() in std library.
When writing copy constructors and copy assignment operators, I simply do this:
Text::Text(const Text& copyfrom) {
data = nullptr; //The object is empty
*this = copyfrom;
}
const Text& Text::operator=(const Text& copyfrom) {
if (this != ©from) {
filename = copyfrom.filename;
entries = copyfrom.entries;
if (copyfrom.data != nullptr) { //If the object is not empty
delete[] data;
}
data = new std::string[entries];
for (int i = 0; i < entries; i++) {
data[i] = copyfrom.data[i];
//std::cout << data[i];
}
std::cout << "Data is assigned" << std::endl;
}
return *this;
}
The equivalent, one would think, would be this:
Text::Text(Text&& movefrom){
*this = movefrom;
}
Text&& Text::operator=(Text&& movefrom) {
if (&movefrom != this) {
filename = movefrom.filename;
entries = movefrom.entries;
data = movefrom.data;
if (data != nullptr) {
delete[] data;
}
movefrom.data = nullptr;
movefrom.entries = 0;
}
return std::move(*this);
}
I'm quite certain this won't work, so my question is: How do you achieve this type of constructor functionality with move semantics?