2011-07-12 21 views
5

Ai đó có thể biện minh cho nhu cầu tư nhân hóa toán tử gán trong thực thi lớp Singleton không?Cần có nhà điều hành gán tư nhân trong một lớp Singleton

Giải quyết vấn đề gì bằng cách đặt Singleton& operator=(Singleton const&); riêng tư?

class Singleton { 
public: 
    static Singleton& Instance() { 
    static Singleton theSingleton; 
    return theSingleton; 
    } 

private: 
    Singleton(); // ctor hidden 
    Singleton(Singleton const&); // copy ctor hidden 
    Singleton& operator=(Singleton const&); // assign op. hidden 
    ~Singleton(); // dtor hidden 
}; 

Trả lời

10

Chuyển nhượng trên một singleton chỉ đơn giản là một hoạt động vô nghĩa vì chỉ có một đối tượng của nó bao giờ nên tồn tại.

Làm nhiệm vụ điều hành tư nhân giúp chẩn đoán đang vô nghĩa như sau:

Singleton& a = Singleton::Instance(); 
Singleton& b = Singleton::Instance(); 
a = b; // Oops, accidental assignment. 
+2

Tôi hiểu ngay cả khi nhà phát triển thực hiện a = b; không có hại gì khi cả hai đối tượng trỏ đến cùng một thể hiện tĩnh của Singleton. Vì vậy, nhà điều hành tư nhân hoặc chuyển nhượng không phải là phải cho một singleton cư xử như mong đợi. –

+1

@PrashanthGN Đúng là điều này không hoạt động nên có 'toán tử =' không nguy hiểm, chỉ là vô nghĩa. –

2

Chỉ có một singleton. Nó không có ý nghĩa để sao chép nó. Bạn cần hai những thứ để có bản sao là lành mạnh và hầu hết các nhà khai thác bản sao cần phải kiểm tra self==&other để được an toàn.

Bí quyết private này là một hack. C++0x does it better.

Begin rant ...

IMHO một Singleton là một mâu thuẫn về. Đó là một sản phẩm của ý tưởng ngớ ngẩn rằng mọi thứ phải là một đối tượng để được đóng gói. Đó là cùng một nỗi đau mà mang một số của Java Math.sin(x) et al.

Cuộc sống của bạn sẽ đơn giản hơn nếu "singleton" đơn giản chỉ là một tập hợp các chức năng miễn phí trong không gian tên. Bất kỳ "thành viên" riêng lẻ nào của singleton có thể được ẩn trong một không gian tên ẩn danh trong tệp .cpp. Đóng gói đạt được, và bạn không có cú pháp thêm cồng kềnh đó.

MyNamespace :: foo(); 

thay vì

MyClass :: instance() .foo(); 
+0

Toán tử gán không thực sự được sử dụng để sao chép. –

+0

Nhưng nó gọi hàm tạo. – 3nixios

+0

Các chức năng trong 'MyNamespace' vẫn có thể cần chia sẻ trạng thái, sau đó sẽ được đóng gói trong một đối tượng có chính xác một đối tượng tồn tại. Và trở lại là singleton. Đó là * hiếm khi * hữu ích, nhưng đôi khi nó * là * thực sự hữu ích. Tất nhiên, không cần phải tuân theo mẫu "Singleton" cụ thể của một lớp, trạng thái này cũng có thể được quản lý bởi một hàm đặc biệt trả về một địa phương tĩnh. Nhưng đây chỉ là một sự khác biệt cú pháp. –

0

Khi bạn sử dụng một singleton lý do bạn thực hiện nó là bởi vì bạn chỉ muốn một thể hiện của một đối tượng của lớp đó. Nói cách khác, không cần phải tạo một bản sao của cá thể vì bạn chỉ có thể có một cá thể. Nó là như nhau cho các nhà xây dựng bản sao.

2

Nếu bạn chỉ muốn một phiên bản, trình tạo bản sao phải ở chế độ riêng tư. Trình chỉ định truy cập toán tử gán không quan trọng, bởi vì nó sẽ không thể sử dụng được.

0

Lý do của tôi là: nếu chỉ có một thể hiện có thể xung quanh, toán tử = có thể được xác định mà không có vấn đề, vì nó sẽ không làm gì đáng kể. nếu chúng ta đặt nó ở chế độ riêng tư, trình biên dịch sẽ thêm một mức độ an toàn cao hơn bằng cách gắn cờ bất kỳ nỗ lực nào để sử dụng toán tử đó làm lỗi.

Cùng một lý do giữ cho trình phá hủy, bằng cách này.

1

Đặt toán tử gán riêng tư không thực sự thay đổi bất cứ điều gì, vì bạn cần hai phiên bản để có thể gán. Nó tương ứng với những gì mọi người có thể mong đợi để xem; thường thì nếu bản sao của bộ tạo bản sao là riêng tư thì toán tử gán cũng được. Tuyên bố một nhà điều hành chuyển nhượng tư nhân chỉ đơn giản là tương ứng với kỳ vọng của mọi người.

0

Tăng cường thừa kế :: không thể sao chép (riêng tư) trong mẫu lớp đơn lẻ hơn để xác định phép xây dựng bản sao cá nhân và toán tử gán.Tuy nhiên,

Các vấn đề liên quan