추가 기능을 제공하기 위해 일련의 추가 기능 템플릿으로 장식 할 수있는 클래스가 있습니다. 각 애드온에는 기본 클래스가 알아야 할 식별 addon_value가 있습니다.템플릿 메타 프로그래밍 OR 작업
아래 코드는 내가하고 싶은 예제입니다. 분명히, main() 함수는 컴파일에 실패합니다. 목표는 CBase :: GetValueOfAddOns()가 각 애드온의 addon_value를 OR 연산하는 값을 알고있는 것입니다. 실제로 GetValueOfAddOns()에서 계산을 수행 할 필요는 없으며 결과에 도달 할 수 있어야합니다. 어떤 도움
template< class T >
class AddOn_A : public T
{
public:
AddOn_A(int x) : T(x)
{};
enum { addon_value = 0x00000001 };
};
template< class T >
class AddOn_B : public T
{
public:
AddOn_B(int x) : T(x)
{};
enum { addon_value = 0x00000010 };
};
class CBase
{
public:
explicit CBase(int x) : x_(x)
{
// error LNK2001: unresolved external symbol "public: virtual int __thiscall CBase::GetValueOfAddOns(void)const " ([email protected]@@UBEHXZ)
int z = GetValueOfAddOns();
};
virtual int GetValueOfAddOns() const = 0;
private:
int x_;
};
// define an empty AddOn
template<class> class empty
{
public:
enum { addon_value = 0x00000000 };
};
// forward declaration and Add-On defaults
template< template<class> class AddOn1 = empty,
template<class> class AddOn2 = empty,
template<class> class AddOn3 = empty >
class CMyClass;
// specialized template for the default case
template<> class CMyClass< empty, empty, empty > : public CBase
{
public:
CMyClass(int x) : CBase(x)
{};
enum { addon_value = 0x00000000 };
};
// actual definition
template< template<class> class AddOn1,
template<class> class AddOn2,
template<class> class AddOn3 >
class CMyClass : public AddOn1<CBase>,
public CMyClass< AddOn2, AddOn3 >
{
public:
CMyClass(int x) : AddOn1<CBase>(x),
CMyClass< AddOn2, AddOn3 >(x)
{};
enum { addon_value = AddOn1<CBase>::addon_value | CMyClass< AddOn2, AddOn3 >::addon_value };
int GetValueOfAddOns() const
{
return addon_value;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
CMyClass<AddOn_A> A(0);
_ASSERT(A.GetValueOfAddOns() == AddOn_A<CBase>::addon_value);
CMyClass< AddOn_A, AddOn_B > AB(0);
_ASSERT(AB.GetValueOfAddOns() == (AddOn_A<CBase>::addon_value | AddOn_B<CBase>::addon_value));
return 0;
}
감사합니다, PaulH
생성자 또는 소멸자에서 가상 메서드를 호출 할 수 없습니다. 이것은 정의되지 않은 동작입니다. –
@Martin York - 그럼, CBase ctor()에서 addon_value를 얻는 방법이 있습니까? 아니면 무리한가? – PaulH
Martin York : 가상 함수를 호출하는 것이 순수하지 않은 한 괜찮습니다. 사람들을 혼란스럽게하는 유일한 단점은 그들이 구축 된 가장 파생 된 객체를 가리킬 뿐이라는 것입니다. 거의 항상 호출이 사실상 가상이 아니라는 것을 의미합니다. 마찬가지로 소멸자 - 소멸자를 완료하지 않은 가장 많이 파생 된 객체가 호출됩니다. – coppro