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;
}
내가 생각할 수있는 가장 좋은 방법은 링커 오류 (컴파일 오류가 아님)이며이를 수행하는 유일한 방법은 Base 클래스의'reg'에 액세스하는 것입니다 (생성자에서). 링커 오류 (실제로 어딘가에 문제의 파생 형식을 사용했음을주의해야합니다 ...) – Nim
@ 님 : 정확히 같은 생각이었습니다 ;-) – Nawaz