2016-10-26 2 views
0

기본 클래스의 자식이 개인 생성자를 갖도록하고 싶습니다. 그런 다음 생성자를 팩토리 클래스 인 친구 클래스를 통해 호출해야합니다.기본 클래스의 자식에서 개인 생성자를 적용하는 방법

class Base: 
    virtual double method1(); 

내가 자료를 상속 Child 원하는 : Base

class Child::Base : 
    public: 
    Child(string s) { 
     //do something 
    } 

    double method1() { 
      return field1; 
    } 

    private: 
    double field1; 
} 

어린이가 string을 분석하여 생성 될 나는 수업 자료를

: 이것은 내 사용 패턴입니다. 그래서 나는 걸리는 Base의 생성자를 가질 수 있습니다. 그러나 생성자를 가상으로 만들 수 없으므로 매개 변수를 적용하지 않습니다.

따라서 Base의 하위 노드는 입력 string에서만 생성 될 수 있도록 Base의 자식을 팩토리 클래스에서 인스턴스화해야합니다. 내 문제는 아무도 누군가 Child을 별도로 인스턴스화하는 것을 막지 못한다는 것입니다. 따라서 Base의 자식 생성자를 비공개로 설정 한 다음 팩토리 클래스를 친구 클래스로 유지하려고합니다.

아이디어가 있으십니까? 이 디자인에 대한 의견조차도 환영합니다.

추 신 : 문자열에서 인스턴스 Child까지 얻는 것은 모든 어린이마다 다를 수 있습니다.

+0

나는 명확하게 질문의 루트를하지 않았다 : 여기에 작업 예제? –

+0

이 질문을 변경했습니다. 질문을 간단한 예제로 추상화하려했지만 분명히 실패했습니다. –

+0

Base private의 기본 생성자를 표시 할 수 있으므로 Child 생성자가 문자열을 매개 변수로 사용하거나 "C2512"라는 기본 생성자를 사용할 수 없습니다. –

답변

2

생성자를 비공개로 설정하지 않고 강제로 추상 클래스로 만들 수 있으므로 파생 클래스 생성을 금지 할 수 있습니다. 당신은 왜 다만 다음의 기본 클래스에 필드 1 움직이지 "나는 자료의 아이들이 항상 FIELD1 갖고 싶어"말한다면

class A 
{ 
    private: 
     struct secret{}; 
     virtual void impossible(secret) = 0; // cannot override this in subclasses 
              // because the parameter type is private 

     template <class X> class AImpl : public X 
     { 
      void impossible(secret) {}; // a nested class can access private members 
     }; 

     template<class X> friend X * AFactory(); 

    public: 
     virtual ~A() {} 
}; 

class B : public A 
{ 
    // void impossible(A::secret) {}; -- can't do that, A::secret is private! 
}; 

template <class X> 
X * AFactory() 
{ 
    return new A::AImpl<X>; 
}; 

int main() 
{ 
    // B b; -- can't do that, B is abstract! 
    B* pB = AFactory<B>(); // Ok 
} 
관련 문제