2016-11-14 133 views
0

我设法摆脱了歧义错误,当使用父解析使用模板从多个父母的重载函数时,但这样会在寻找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 &)" 
+1

你得到的错误是什么? – NathanOliver

+1

'this-> ObjectHandler :: AddObjectImpl(obj);'不是虚拟调用。你应该尝试'((ObjectHandler *)this) - > AddObjectImpl(obj)'。 – Franck

+0

@Franck这似乎工作,但我不明白为什么它不是虚拟呼叫,以及为什么你的答案有效。如果你可以添加你的答案,所以我可以选择它,谢谢:) – ptrl4me

回答

0

在你的代码,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()