2012-05-11 17 views
5

Giả sử tôi có một lớp học với một phương pháp nhà máyNgăn chặn instantiation của một đối tượng bên ngoài phương pháp nhà máy

class A { 
public: 
    static A* newA() 
    { 
    // Some code, logging, ... 
    return new A(); 
    } 
} 

Có thể để ngăn chặn sự instantiation của một đối tượng của lớp này với một new, do đó phương pháp nhà máy là phương pháp duy nhất để tạo một thể hiện của đối tượng là gì?

+2

Độc thân là ác. Xem tại đây: http://programmers.stackexchange.com/questions/40373/so-singletons-are-bad-then-what –

+2

@Truth: Đây không giống như một singleton. –

+0

@OliCharlesworth: Một nhà máy trả về một thể hiện của chính nó và ngăn chặn bất kỳ ai khác khởi tạo nó? Có vẻ rất nguy hiểm. –

Trả lời

8

Chắc chắn; chỉ cần thực hiện tin constructor (bảo vệ nếu điều này là một lớp cơ sở):

class A { 
public: 
    static A* newA() 
    { 
    // Some code, logging, ... 
    return new A(); 
    } 

private: 
    A() {} // Default constructor 
}; 

Bạn nên làm cho các nhà xây dựng bản sao tin/bảo vệ là tốt, nếu có yêu cầu.

Và như thường lệ, bạn nên cân nhắc việc trả lại con trỏ thông minh thay vì con trỏ thô, để đơn giản hóa các vấn đề về quản lý bộ nhớ.

+0

Câu trả lời này chỉ là tiếng hét của 'std :: unique_ptr' ... Edit: Meh, đừng đi ghost-chỉnh sửa câu trả lời của bạn. : P – Xeo

+0

Cảm ơn bạn đã trả lời. Đối với các con trỏ thông minh - tôi biết. Tôi thường sử dụng chúng. Nhưng quản lý bộ nhớ cho đối tượng cụ thể này hơi phức tạp và không thể sử dụng 'shared_ptr'everywhere vì lý do hiệu suất. – Tibor

+0

Tôi luôn tự hỏi, giả sử nhà máy của bạn trả về một unique_ptr nhưng thực sự muốn một shared_ptr (hoặc ngược lại), làm thế nào để làm điều đó? – stijn

3

Bạn cũng có thể muốn làm cho các nhà xây dựng bản sao tin cũng hay với mới C++ 11 cú pháp bạn có thể nói một cách rõ ràng các trình biên dịch không sao chép nó và làm cho các nhà xây dựng mặc định riêng với một cái gì đó như thế này:

struct NonCopyable { 
    NonCopyable & operator=(const NonCopyable&) = delete; 
    NonCopyable(const NonCopyable&) = delete; 
    NonCopyable() = default; 
}; 

class A : NonCopyable { 
public: 
    static std::shared_ptr<A> newA() 
    { 
    // Some code, logging, ... 
    return std::make_shared<A>(); 
    } 

private: 
    A() {} // Default constructor 
}; 

Cách C++ 03 thường giống như sau:

class A { 
public: 
    static A* newA() 
    { 
    // Some code, logging, ... 
    return new A(); 
    } 

private: 
    A() {}      // no outsider default constructor 
    A(const A& rhs);    // no copy 
    A& operator=(const A& rhs); // no assignment 
}; 

int main() 
{ 
    A x;  // C2248 
    A y(x);  // C2248 
    x = y;  // C2248 
    A* p = A::newA(); // OK 
    std::cin.get(); 
    return 0; 
} 
+0

Với C++ 11 bạn thực sự nên tránh trả về một con trỏ trần. –

+0

Điểm tốt, thực sự tôi sẽ tránh hầu hết điều này và chỉ sử dụng 'std :: unique_ptr' trong hầu hết các trường hợp. – AJG85