Chúng tôi đã đi qua chủ đề này gần đây trong lớp EECS của tôi. Nếu bạn muốn xem chi tiết các bài giảng, hãy truy cập http://umich.edu/~eecs381/lecture/IdiomsDesPattsCreational.pdf
Có hai cách mà tôi biết để tạo một lớp Singleton chính xác.
Cách thứ nhất:
Thực hiện nó tương tự như cách bạn có nó trong ví dụ của bạn. Về phần hủy diệt, "Singletons thường chịu đựng thời gian chạy chương trình; hầu hết các hệ điều hành sẽ phục hồi bộ nhớ và hầu hết các tài nguyên khác khi chương trình chấm dứt, do đó có một lập luận cho việc không lo lắng về điều này."
Tuy nhiên, đó là một thực hành tốt để làm sạch khi chấm dứt chương trình. Do đó, bạn có thể làm điều này với một lớp SingletonDestructor tĩnh và khai báo đó là một người bạn trong Singleton của bạn.
class Singleton {
public:
static Singleton* get_instance();
// disable copy/move -- this is a Singleton
Singleton(const Singleton&) = delete;
Singleton(Singleton&&) = delete;
Singleton& operator=(const Singleton&) = delete;
Singleton& operator=(Singleton&&) = delete;
friend class Singleton_destroyer;
private:
Singleton(); // no one else can create one
~Singleton(); // prevent accidental deletion
static Singleton* ptr;
};
// auxiliary static object for destroying the memory of Singleton
class Singleton_destroyer {
public:
~Singleton_destroyer { delete Singleton::ptr; }
};
Singleton_destroyer sẽ được tạo khi khởi động chương trình và "khi chương trình kết thúc, tất cả các đối tượng toàn cầu / tĩnh bị phá hủy bởi mã tắt thư viện thời gian chạy (được chèn bởi trình liên kết), do đó ,_destroyer sẽ bị hủy, trình hủy của nó sẽ xóa Singleton, chạy nó kẻ hủy diệt. "
Cách thứ hai
Đây được gọi là Meyers Singleton, được tạo bởi thuật sĩ C ++ Scott Meyers. Đơn giản chỉ cần định nghĩa get_instance () khác nhau. Bây giờ bạn cũng có thể thoát khỏi biến thành viên con trỏ.
// public member function
static Singleton& Singleton::get_instance()
{
static Singleton s;
return s;
}
Điều này là gọn gàng vì giá trị được trả về là do tham chiếu và bạn có thể sử dụng .
cú pháp thay vì ->
truy cập các biến thành viên.
"Trình biên dịch tự động xây dựng mã tạo lần đầu tiên thông qua khai báo, không phải sau đó và sau đó xóa đối tượng tĩnh khi kết thúc chương trình."
Cũng lưu ý rằng với Meyers Singleton, bạn "có thể gặp tình huống rất khó khăn nếu các đối tượng dựa vào nhau tại thời điểm chấm dứt - khi nào Singleton biến mất so với các đối tượng khác? Nhưng đối với các ứng dụng đơn giản, điều này hoạt động tốt."