2013-01-22 2 views
4

특정 기본 클래스에서 파생 된 클래스에 대한 등록 기관의 구현이 있습니다. 각 파생 클래스를 자체적으로 등록하고 프로세스에 자체에 대한 정보를 제공하려는 의도가 있습니다. 아래 예제에서는 문자열을 통해 제공됩니다.파생 형식의 등록 강제 적용

내가 누락 된 부분은 Base에서 파생 된 클래스를 정적 ​​멤버 reg 초기화를 통해 강제로 등록하는 방법입니다. 즉, 파생 클래스가 정적 멤버를 정의/초기화하지 않으면 컴파일러에서 오류가 발생할 수 있습니까?

public: 
    Base() { reg.blah(); } 

내가 할 수있는 다음 CRTP 기본 클래스에서 더미 생성자에서 호출 한 후 void blah() { }과 :

struct Registrar { 
    Registrar(string type) { 
    registry().push_back(type); 
    } 
    static vector<string> & registry() { 
    static vector<string> * derivedTypes = new vector<string>; 
    return *derivedTypes; 
    } 
}; 

//CRTP 
template <typename Derived> 
class Base 
{ 
    static Registrar reg; 
}; 

class Derived1 : public Base<Derived1> {/*Class definition*/}; 
class Derived2 : public Base<Derived2> {/*Class definition*/}; 
class Derived3 : public Base<Derived3> {/*Class definition*/}; 
//... 

//Initialize the static members of each derived type 
//Commenting out any of the following 3 lines doesn't produce an error. 
//Ideally, I want it to produce a compile error. 
template<> Registrar Base<Derived1>::reg("Derived1"); 
template<> Registrar Base<Derived2>::reg("Derived2"); 
template<> Registrar Base<Derived3>::reg("Derived3"); 

int main() { 

    cout << "Registered Types:" << endl; 
    for(vector<string>::const_iterator it = Registrar::registry().begin(); 
     it != Registrar::registry().end(); ++it) { 
    cout << *it << endl; 
    } 

    return 0; 
} 
+1

내가 생각할 수있는 가장 좋은 방법은 링커 오류 (컴파일 오류가 아님)이며이를 수행하는 유일한 방법은 Base 클래스의'reg'에 액세스하는 것입니다 (생성자에서). 링커 오류 (실제로 어딘가에 문제의 파생 형식을 사용했음을주의해야합니다 ...) – Nim

+0

@ 님 : 정확히 같은 생각이었습니다 ;-) – Nawaz

답변

1

당신은 적어도 등록에 더미 기능을 추가하여 g의 ++에 링커 오류가 발생할 수 있습니다 이 문제를 해결할 더 우아한 방법을 보지 못한다.