#include <cstring>
#include <iostream>
#include <utility>
#include <vector>

// 一个自己管理内存的缓冲区，演示拷贝和移动的区别
class Buffer {
public:
    explicit Buffer(size_t size) : data_(new char[size]), size_(size) {
        std::cout << "construct " << size_ << " bytes" << std::endl;
    }
    ~Buffer() { delete[] data_; }

    // 拷贝构造：新开一块内存，把内容复制过来（深拷贝，慢）
    Buffer(const Buffer& other) : data_(new char[other.size_]), size_(other.size_) {
        std::memcpy(data_, other.data_, size_);
        std::cout << "copy " << size_ << " bytes" << std::endl;
    }

    // 移动构造：直接把对方的指针拿过来，再把对方置空（快，不复制数据）
    Buffer(Buffer&& other) noexcept : data_(other.data_), size_(other.size_) {
        other.data_ = nullptr;
        other.size_ = 0;
        std::cout << "move " << size_ << " bytes" << std::endl;
    }

    Buffer& operator=(const Buffer&) = delete;
    Buffer& operator=(Buffer&&) = delete;
    size_t size() const { return size_; }

private:
    char* data_;
    size_t size_;
};

Buffer makeBuffer() {
    Buffer b(1024);
    return b;  // 编译器会直接在调用方构造（返回值优化），连移动都省了
}

int main() {
    Buffer a(1024 * 1024);
    Buffer b = a;             // a 还要用，只能拷贝
    Buffer c = std::move(a);  // a 不再用了，把它的内存“搬”给 c
    std::cout << "a.size() = " << a.size() << ", c.size() = " << c.size() << std::endl;
    Buffer d = makeBuffer();
    std::cout << "--- vector ---" << std::endl;
    std::vector<Buffer> v;
    v.reserve(2);
    v.push_back(Buffer(16));   // 临时对象是右值，自动走移动
    v.emplace_back(32);        // 直接在 vector 里构造，连移动都没有
    return 0;
}
