Để 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).