C++多模板纯虚拟继承
问题描述:
我设法摆脱了歧义错误,当使用父解析使用模板从多个父母的重载函数时,但这样会在寻找AddObjectImpl时出现链接错误,这很奇怪,因为该函数是虚拟的。C++多模板纯虚拟继承
template<typename T>
class ObjectHandler
{
public:
virtual void AddObjectImpl(T& obj) = 0;
virtual void ClearObjectImpl(T& obj) = 0;
};
class INTERFACE_API IModel
: public ObjectHandler<type1>,
public ObjectHandler<type2>
{
public:
template<typename T>
void AddObject(T& obj)
{
this->ObjectHandler<T>::AddObjectImpl(obj);
}
template<typename T>
void ClearObject(T& obj)
{
this->ObjectHandler<T>::ClearObjectImpl(obj);
}
};
// In different project
class CModel : public IModel
{
virtual void AddObjectImpl(type1& o) override;
virtual void AddObjectImpl(type2& o) override;
virtual void ClearObjectImpl(type1& o) override;
virtual void ClearObjectImpl(type2& o) override;
}
// And then the implementation ...
EDIT1:错误在呼叫发生ADDOBJECT:
error LNK2019: unresolved external symbol
"__declspec(dllimport) public: virtual void __cdecl
ObjectHandler<class type1>::AddObjectImpl(class type1 &)"
(/*removed*/) referenced in function "public: void __cdecl
IModel::AddObject<class type1>(class type1 &)"
答
在你的代码,this->ObjectHandler<T>::AddObjectImpl(obj);
不是虚拟/动态调用但因为你有资格你的电话一个静态调用。
您应该将其替换为((ObjectHandler<T>*) this)->AddObjectImpl(obj)
以调用正确的虚拟方法。
在代码等
呼叫
base->Base::f();
静态调用基方法Base::f
而((Base*) base)->f()
通过在虚拟方法表搜索它动态地调用Derived::f
。这与你的代码是一样的。
注意与
class Base {
public:
virtual void f() = 0;
};
class Derived : public Base {
public:
virtual void f() {}
};
Base* base = new Derived;
base->Base::f();
编译器编译它,即使它可以推断出它是一个纯虚方法的静态调用。最后,链接器抱怨错误消息undefined reference to Base::f()
你得到的错误是什么? – NathanOliver
'this-> ObjectHandler :: AddObjectImpl(obj);'不是虚拟调用。你应该尝试'((ObjectHandler *)this) - > AddObjectImpl(obj)'。 –
Franck
@Franck这似乎工作,但我不明白为什么它不是虚拟呼叫,以及为什么你的答案有效。如果你可以添加你的答案,所以我可以选择它,谢谢:) – ptrl4me