C++
Beginner
1 min read
Move Semantics and the Rule of Five
Example
#include <iostream>
#include <utility> // std::move, std::exchange
class Buffer {
public:
explicit Buffer(std::size_t size)
: data_(new int[size]), size_(size) {
std::cout << "Constructed buffer[" << size_ << "]\n";
}
// Destructor
~Buffer() {
delete[] data_;
std::cout << "Destroyed buffer[" << size_ << "]\n";
}
// Copy constructor (deep copy)
Buffer(const Buffer& other)
: data_(new int[other.size_]), size_(other.size_) {
std::copy(other.data_, other.data_ + size_, data_);
std::cout << "Copied buffer[" << size_ << "]\n";
}
// Copy-assignment
Buffer& operator=(const Buffer& other) {
if (this == &other) return *this;
delete[] data_;
size_ = other.size_;
data_ = new int[size_];
std::copy(other.data_, other.data_ + size_, data_);
return *this;
}
// Move constructor (steals resources)
Buffer(Buffer&& other) noexcept
: data_(std::exchange(other.data_, nullptr))
, size_(std::exchange(other.size_, 0)) {
std::cout << "Moved buffer[" << size_ << "]\n";
}
// Move-assignment
Buffer& operator=(Buffer&& other) noexcept {
if (this == &other) return *this;
delete[] data_;
data_ = std::exchange(other.data_, nullptr);
size_ = std::exchange(other.size_, 0);
return *this;
}
std::size_t size() const { return size_; }
private:
int* data_;
std::size_t size_;
};
int main() {
Buffer a(8);
Buffer b = std::move(a); // move constructor
Buffer c(4);
c = std::move(b); // move-assignment
std::cout << "c.size() = " << c.size() << "\n";
return 0;
}