templates may not be ‘virtual’
给定下面的代码,编译器将显示一条消息,指出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | template < class FOO_TYPE> class CFoo{ public: ... template < class BAR_TYPE > virtual void doSomething( const CBar<BAR_TYPE> &); // here's the error ... virtual ~CFoo(); protected: MyClass < FOO_TYPE > * m_pClass; }; template < class FOO_TYPE > template < class BAR_TYPE > void CFoo<FOO_TYPE>::doSomething( const CBar<BAR_TYPE> & refBar ){ ... } |
要想知道这是违法的最简单的原因是考虑vtable。当然,这只是一个常见的实现,其他实现是允许的。但是在C++中所有EDCOX1的1个函数都被设计成可以用VTABLE实现。
现在,在
现在,您可能只需要vtable中的一个条目。在这种情况下,您可以这样写:
1 2 3 4 5 6 7 8 9 10 | template < class FOO_TYPE, class BAR_TYPE> class CFoo{ public: ... virtual void doSomething( const CBar<BAR_TYPE> &); // now OK. ... virtual ~CFoo(); protected: MyClass < FOO_TYPE > * m_pClass; }; |
这意味着用于
您可以使用我们在Symbian中所称的"模板设计模式"。下面是示例代码,您可以了解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | class Base { public: virtual int DoSomething() = 0; protected: Base(); }; class IntermediateBase : public Base { protected: IntermediateBase(void* aSomeParam, void* aArg) : iSomeParam(aSomeParam) , iArgs(aArg) {} virtual int DoSomething() = 0; protected: void* iSomeParam; void* iArgs; }; template <class TYPE, class INPUT> class ConcreteClass : public IntermediateBase { typedef int (TYPE::*MemberFuncPtr)(const INPUT&); public: ConcreteClass(TYPE& aCommandType, INPUT& aArgumentsToCommand, MemberFuncPtr aMFP) : IntermediateBase(static_cast<TYPE*>(&aCommandType), static_cast<INPUT*>(&aArgumentsToCommand) ) , iMFP(aMFP) {} virtual int DoSomething() // VIRTUAL AND INLINE Note - dont make it // virtual and inline in production if // possible to avoid out-of-line copy { return static_cast<TYPE*>(iSomeParam)->*ConcreteClass::iMFP) (*(static_cast<INPUT*>(iArgs)); } private: MemberFuncPtr iMFP; }; |
如果您真的需要使这个方法成为虚拟的,可以考虑使
编辑:如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | // non-templated base class class BarBase { // common methods go here.. }; template <typename BAR_TYPE> class CBar : public BarBase { // implement methods from BarBase ... }; template < class FOO_TYPE> class CFoo{ public: ... // now we take the base type, and this method does not need to be a template virtual void doSomething( BarBase const* ptrBar ); ... virtual ~CFoo(); protected: MyClass < FOO_TYPE > * m_pClass; }; template < class FOO_TYPE > void CFoo<FOO_TYPE>::doSomething( BarBase const* ptrBar ){ .. } |
嗯,错误信息非常清楚。成员函数模板不能是虚拟的。如何解决这个问题取决于您的问题,但最简单的方法是使成员函数非虚拟化,并重新考虑您的设计。