Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Ngăn chặn sao chép đối tượng (Prevent Object Copy) trong C++


Để ngăn không cho đối tượng được copy (copy constructor) hoặc gán (assignment), khai báo private hoặc = delete (C++11).

Cách 1: Private + không định nghĩa (C++98/03)

class NonCopyable {
    // Chỉ khai báo, không định nghĩa
    NonCopyable(const NonCopyable&);
    NonCopyable& operator=(const NonCopyable&);
public:
    NonCopyable() {}
};

int main() {
    NonCopyable a;
    NonCopyable b = a; // LỖI LINKER: undefined reference to private copy ctor
    b = a;             // LỖI LINKER: undefined reference to private operator=
}

Cách 2: = delete (C++11 - Khuyên dùng)

class NonCopyable {
public:
    NonCopyable() = default;
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable& operator=(const NonCopyable&) = delete;
};

int main() {
    NonCopyable a;
    NonCopyable b = a; // LỖI COMPILE: use of deleted function
    b = a;             // LỖI COMPILE
}

Cách 3: Kế thừa từ base non-copyable

class NonCopyableBase {
protected:
    NonCopyableBase() = default;
    ~NonCopyableBase() = default;
    NonCopyableBase(const NonCopyableBase&) = delete;
    NonCopyableBase& operator=(const NonCopyableBase&) = delete;
};

class MyClass : private NonCopyableBase {
    // MyClass cũng không copy được
};

Lưu ý: Move Semantics

Với C++11, có thể cho phép move nhưng cấm copy:

class MovableOnly {
public:
    MovableOnly() = default;
    MovableOnly(const MovableOnly&) = delete;
    MovableOnly& operator=(const MovableOnly&) = delete;
    MovableOnly(MovableOnly&&) = default;       // Cho phép move
    MovableOnly& operator=(MovableOnly&&) = default;
};

Ứng dụng thực tế

  • Class quản lý tài nguyên độc quyền (file handle, socket, mutex, GPU resource).
  • std::unique_ptr, std::mutex, std::thread, std::atomic đều non-copyable.
  • Base class polymorphic (tránh slicing).