2011-01-10 119 views
48

可能重複:
What is the use of making constructor private in a class?私有構造

我們在哪裏需要私有構造?我們如何實例化一個具有私有構造函數的類?

+2

另請參閱http://stackoverflow.com/questions/2062560/what-is-the-use-of-making-constructor-private-in-a-class – StuartLC 2011-01-10 15:58:58

+0

好的發現,也是這個問題的接受答案是對C++無用 - >在C++中創建一類靜態函數是不好的,我們不受「純粹的」OOP思維限制。 – 2011-01-10 17:22:11

+0

http://stackoverflow.com/questions/2062560/what-is-the-use-of-making-constructor-private-in-a-class/16547184#16547184 – 2013-05-23 15:12:03

回答

64

私有構造函數意味着用戶不能直接實例化一個類。相反,您可以使用類似於Named Constructor Idiom的東西創建對象,您可以在其中創建和返回類的實例的類函數。

命名構造函數習語用於更直觀地使用類。 C++ FAQ中提供的示例適用於可用於表示多個座標系的類。

這是從鏈接直接拉。它是一個代表不同座標系中點的類,但它可以用來表示矩形和極座標點,所以爲了使用戶更直觀,可以使用不同的函數來表示返回的Point表示的座標系。

#include <cmath>    // To get std::sin() and std::cos() 

class Point { 
public: 
    static Point rectangular(float x, float y);  // Rectangular coord's 
    static Point polar(float radius, float angle); // Polar coordinates 
    // These static methods are the so-called "named constructors" 
    ... 
private: 
    Point(float x, float y);  // Rectangular coordinates 
    float x_, y_; 
}; 

inline Point::Point(float x, float y) 
    : x_(x), y_(y) { } 

inline Point Point::rectangular(float x, float y) 
{ return Point(x, y); } 

inline Point Point::polar(float radius, float angle) 
{ return Point(radius*std::cos(angle), radius*std::sin(angle)); } 

已經有很多其他響應也契合了爲什麼私有構造函數在C++(其中Singleton模式)使用過的精神。

你可以用它做的另一件事是prevent inheritance of your class,因爲派生類將無法訪問你的類的構造函數。當然,在這種情況下,你仍然需要一個創建類的實例的函數。

29

一個常見的用法是單例模式,您只希望該類的一個實例存在。在這種情況下,你可以提供一個static方法來實現對象的實例化。這樣可以控制實例化特定類的對象的數量。

2

這是常見的,當你想實現一個單身人士。該類可以有一個靜態的「工廠方法」來檢查類是否已經被實例化,如果沒有,就調用該構造器。

5

如果有其他方法可以生成實例,那麼使構造函數保密是合理的。明顯的例子是模式Singleton(每個調用返回相同的實例)和Factory(每個調用通常創建新實例)。

1

例如,您可以調用朋友類或朋友函數中的私有構造函數。

Singleton pattern通常使用它來確保沒有人創建更多預期類型的​​實例。

6

當你不希望你的類被用戶實例化時,私有構造函數非常有用。爲了實例化這樣的類,你需要聲明一個靜態方法,它執行'new'並返回指針。

有私人課程的班級不能放在STL容器中,因爲他們需要一個副本。

1

一個常見的用途是模板的typedef解決方法類,如下列:

template <class TObj> 
class MyLibrariesSmartPointer 
{ 
    MyLibrariesSmartPointer(); 
    public: 
    typedef smart_ptr<TObj> type; 
}; 

顯然,一個公共非執行構造函數藏漢工作,但私人construtor引發一個編譯時錯誤,而不是一個鏈接時出錯,如果有人試圖安置MyLibrariesSmartPointer<SomeType>而不是MyLibrariesSmartPointer<SomeType>::type,這是需要的。