2011-01-10 93 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,这是需要的。