Move semantics is well-known topic in C++:What is move semantics?.
Immutability is another important concept in programming.
I want to combine the 2 to make efficient immutable objects.
From the above link, I create a simple string class:
The main point is in the 2 "append" methods.
#include <iostream>
#include <cstring>
#include <algorithm>
class string {
char *data;
public:
string(const char *p) {
size_t size = std::strlen(p) + 1;
data = new char[size];
std::memcpy(data, p, size);
}
~string() {
delete[] data;
}
string(const string &that) {
size_t size = std::strlen(that.data) + 1;
data = new char[size];
std::memcpy(data, that.data, size);
}
string(string &&that) {
data = that.data;
that.data = nullptr;
}
// Copied from the link above but make the object no longer immutable, so discard it
// string& operator=(string that) {
// std::swap(data, that.data);
// return *this;
// }
// "this" is a normaly pointer, but we show it as a rvalue reference
string& append(/*string &&this, */ const char *p) {
std::cout << "move" << std::endl;
size_t size = std::strlen(data) + std::strlen(p) + 1;
char *tmpData = new char[size];
std::strcpy(tmpData, data);
std::strcat(tmpData, p);
delete[] data;
data = tmpData;
return *this;
}
// "this" is a normaly pointer, but we show it as a reference
string append(/*const string &this, */ const char *p) const {
std::cout << "copy" << std::endl;
return string(data, p); // use returned value optimization (copy elision)
}
private:
// Created to allow copy elision in "append copy"
string(const char *start, const char *end) {
size_t size = std::strlen(start) + std::strlen(end) + 1;
data = new char[size];
std::strcpy(data, start);
std::strcat(data, end);
}
};
int main() {
string a("a");
string b = a.append("...");
string c = a.append("1...").append("2...");
string d = string("s").append("1...").append("2...");
return 0;
}
(The compiler discards "append copy" and only calls "append move".)
I know the code does not work as expected the idea is to be able to use move semantics with "this" pointer and the compiler able to choose among the 2 "append" methods. So the above program will work like this:
string b = a.append("...");
will call "append copy"
string c = a.append("1...").append("2...");
will call "append copy", then "append move"
string d = string("s").append("1...").append("2...");
will call "append move", then "append move"`
If anyone has some insight to make it possible, I am pleased to learn it.