Trang tài liệu
Khóa học C++ nền tảng
Chương 13. Idiom trong C++
Đặc ngữ Copy-Write

Đặc ngữ Copy-Write

Đặc ngữ Copy-Write, đôi khi được gọi là đặc ngữ Copy-on-Write (CoW) hoặc "lazy copying", là một kỹ thuật được sử dụng trong lập trình để giảm thiểu chi phí sao chép các đối tượng lớn. Nó giúp giảm số lượng thao tác sao chép thực tế bằng cách sử dụng các tham chiếu được chia sẻ tới các đối tượng và chỉ sao chép dữ liệu khi cần sửa đổi.

Hãy hiểu điều này với một ví dụ đơn giản:

#include <iostream>
#include <memory>
 
class MyString {
public:
    MyString(const std::string &str) : data(std::make_shared<std::string>(str)) {}
 
    // Sử dụng cùng một dữ liệu được chia sẻ để sao chép.
    MyString(const MyString &other) : data(other.data) { 
        std::cout << "Copied using the Copy-Write idiom." << std::endl;
    }
 
    // Chỉ tạo một bản sao nếu muốn sửa đổi dữ liệu.
    void write(const std::string &str) {
        // Kiểm tra xem có nhiều hơn một tham chiếu không.
        if(!data.unique()) {
            data = std::make_shared<std::string>(*data);
            std::cout << "Copy is actually made for writing." << std::endl;
        }
        *data = str;
    }
 
private:
    std::shared_ptr<std::string> data;
};
 
int main() {
    MyString str1("Hello");
    MyString str2 = str1; // Không có thao tác sao chép, chỉ chia sẻ tài liệu tham khảo.
 
    str1.write("Hello, World!"); // Đây là nơi xảy ra sự trùng lặp thực tế.
    return 0;
}

Trong ví dụ này, chúng ta có một lớp MyString mô phỏng đặc ngữ Copy-Write. Khi một đối tượng MyString được tạo, nó sẽ tạo một shared_ptr trỏ đến một chuỗi. Khi một đối tượng MyString được sao chép, nó không thực hiện bất kỳ thao tác sao chép thực tế nào mà chỉ tăng số lượng tham chiếu của đối tượng được chia sẻ. Cuối cùng, khi hàm write được gọi, nó sẽ kiểm tra xem có nhiều hơn một tham chiếu đến dữ liệu hay không và nếu có, nó thực sự tạo một bản sao mới và cập nhật tham chiếu đó. Bằng cách này, có thể tránh được các bản sao không cần thiết cho đến khi chúng thực sự cần thiết để sửa đổi.