2011-01-10 12 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

+0

잘 찾아 볼 수 있으며이 질문에 대한 대답은 다음과 같습니다. 쓸데없는 C++ +> C++에서 정적 함수의 클래스를 만드는 것은 좋지 않습니다. 우리는 "순수한"OOP 마인드에 구속받지 않습니다. –

+0

http://stackoverflow.com/questions/2062560/what-is-the-use-of-making-constructor-private-in-a-class/16547184#16547184 –

답변

64

개인 생성자는 사용자가 클래스를 직접 인스턴스화 할 수 없다는 것을 의미합니다. 대신 Named Constructor Idiom과 같은 것을 사용하여 객체를 만들 수 있습니다. static 클래스 함수를 사용하면 클래스의 인스턴스를 만들고 반환 할 수 있습니다.

명명 된 생성자 관용구는 클래스를보다 직관적으로 사용하기위한 것입니다. C++ FAQ에서 제공되는 예제는 여러 좌표 시스템을 표현하는 데 사용할 수있는 클래스에 대한 것입니다.

이것은 링크에서 직접 잡아 당깁니다. 다른 좌표계의 점을 나타내는 클래스이지만 Rectangular 및 Polar 좌표 점을 모두 나타내는 데 사용할 수 있으므로 사용자가 더 직관적으로 만들 수 있도록 반환 된 좌표계를 나타내는 데 사용되는 함수는 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++ (그 중 싱글 톤 패턴)에서 사용되는 이유에 대한 정신에 잘 들어 맞는 반응이 많이 있습니다.

파생 클래스가 클래스의 생성자에 액세스 할 수 없기 때문에 당신이 할 수있는 또 다른 일은 prevent inheritance of your class입니다. 물론이 상황에서 클래스의 인스턴스를 만드는 함수가 필요합니다.

+1

잘 모르겠지만 copy ctor를 사용하는 것이 좋습니다. RVO 때문에 그것에 대해 확실하지 않습니다. –

+3

@Pawel - C++ FAQ 예제는 클래스에 프리미티브 멤버 (두 개의 'float') 만 있기 때문에 'Point'에 대한 복사 생성자를 정의하지 않으므로 컴파일러의 기본 복사 생성자 (예 : 얕은 복사본)가 예제에 충분합니다. – birryree

+1

+1 마지막으로, Singleton 또는 Factory가 아닌 예입니다. 명명 된 생성자가 훨씬 유용하게 보입니다. – chrisaycock

29

일반적으로 하나의 클래스 인스턴스 만 존재하게하는 싱글 톤 패턴이 일반적으로 사용됩니다. 이 경우 객체의 인스턴스화를 수행하는 static 메소드를 제공 할 수 있습니다. 이 방법으로 특정 클래스의 인스턴스화 된 객체 수를 제어 할 수 있습니다.

+17

+1. 나는 특정 관용구의 경우 사용법으로 싱글 톤을 언급 할 때 항상 downvoted를 얻는다. 그 일이 너에게 일어나기를 원하지 마라! :) –

2

싱글 톤을 구현하려는 경우 일반적입니다. 클래스는 클래스가 이미 인스턴스화되었는지 검사하고 그렇지 않은 경우 생성자를 호출하는 정적 "팩토리 메소드"를 가질 수 있습니다.

5

인스턴스를 생성 할 수있는 다른 방법이 있으면 생성자를 비공개로 만드는 것이 합리적입니다. 명백한 예는 Singleton (모든 호출이 동일한 인스턴스를 반환 함) 및 Factory (모든 호출 , 대개 새 인스턴스 만들기)입니다.

1

예를 들어, 친구 클래스 또는 friend 함수에서 개인 생성자를 호출 할 수 있습니다.

Singleton pattern은 일반적으로 아무도 원하는 유형의 인스턴스를 더 이상 만들지 않도록하기 위해이 매개 변수를 사용합니다.

6

개인 생성자는 사용자가 클래스를 인스턴스화하지 못하도록 할 때 유용합니다. 이러한 클래스를 인스턴스화하려면 정적 메서드를 선언해야합니다.이 메서드는 'new'를 실행하고 포인터를 반환합니다.

개인 ctors가있는 클래스는 복사본 ctor가 필요하므로 STL 컨테이너에 넣을 수 없습니다.

1

하나 개의 일반적인 사용은 다음과 같이 템플릿 형식 정의의 해결 클래스입니다 :

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

공공 비 구현 생성자 aswell 일 것이지만, 개인 생성자는 링크 타임 오류 대신 컴파일시 오류가 발생합니다 누군가가 MyLibrariesSmartPointer<SomeType>::type 대신에 MyLibrariesSmartPointer<SomeType>을 instatiate하려고한다면, 그것은 바람직합니다.