Skip to content

Instantly share code, notes, and snippets.

@nulledge
Last active October 14, 2024 10:22
Show Gist options
  • Save nulledge/324e23840c3452b46eecac1914f0a6c1 to your computer and use it in GitHub Desktop.
Save nulledge/324e23840c3452b46eecac1914f0a6c1 to your computer and use it in GitHub Desktop.
C++ copy and move example
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
// Reference
// https://learn.microsoft.com/ko-kr/cpp/cpp/move-constructors-and-move-assignment-operators-cpp?view=msvc-170
class Block {
public:
Block(size_t length=0): buffer(vector<int>(length)) {
cout << "Block initialized (length=" << length << ")" << endl;
}
Block(const Block& block): buffer(block.buffer) {
cout << "Block copied (length=" << buffer.size() << ")" << endl;
}
Block(Block&& block) {
*this = move(block);
cout << "Block moved (length=" << buffer.size() << ")" << endl;
}
~Block() {
cout << "Block deleted (length=" << buffer.size() << ")" << endl;
}
Block& operator=(const Block& block) {
buffer = block.buffer;
return *this;
}
Block& operator=(Block&& block) {
buffer = move(block.buffer);
return *this;
}
// Reference
// https://stackoverflow.com/questions/10360232/how-do-i-use-a-chain-of-operator-overloads-without-modifying-the-operands
Block& operator+=(const Block& block) {
buffer.insert(
buffer.end(),
block.buffer.begin(),
block.buffer.end()
);
return *this;
}
public:
vector<int> buffer;
};
Block operator+(Block a, const Block& b) {
// Note that "return a+=b;" invokes the copy constructor, not the move constructor.
// The type of "a+=b" is Block& but the return type is Block.
a += b;
return a;
}
int main () {
cout << "copy" << endl;
{
Block block(10);
// Block initialized (length=10)
Block copied = block;
// Block copied (length=10)
// Block deleted (length=10)
// Block deleted (length=10)
}
cout << endl;
cout << "move" << endl;
{
Block block(20);
// Block initialized (length=20)
Block moved = move(block);
// Block moved (length=20)
// Block deleted (length=20)
// Block deleted (length=0)
}
cout << endl;
cout << "operator+ with constructors(rvalue)" << endl;
{
Block sum = Block(10) + Block(20) + Block(30) + Block(40);
// Block initialized (length=40)
// Block initialized (length=30)
// Block initialized (length=20)
// Block initialized (length=10)
// Block moved (length=30)
// Block moved (length=60)
// Block moved (length=100)
// Block deleted (length=0)
// Block deleted (length=0)
// Block deleted (length=0)
// Block deleted (length=20)
// Block deleted (length=30)
// Block deleted (length=40)
cout << "sum.buffer.size() = " << sum.buffer.size() << endl;
// sum.buffer.size() = 100
// Block deleted (length=100)
}
cout << endl;
cout << "operator+ with variables(lvalue)" << endl;
{
Block a(10), b(20), c(30), d(40);
// Block initialized (length=10)
// Block initialized (length=20)
// Block initialized (length=30)
// Block initialized (length=40)
Block sum = a + b + c + d;
// Block copied (length=10)
// Block moved (length=30)
// Block moved (length=60)
// Block moved (length=100)
// Block deleted (length=0)
// Block deleted (length=0)
// Block deleted (length=0)
cout << "sum.buffer.size() = " << sum.buffer.size() << endl;
// sum.buffer.size() = 100
// Block deleted (length=100)
// Block deleted (length=40)
// Block deleted (length=30)
// Block deleted (length=20)
// Block deleted (length=10)
}
cout << endl;
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment