2016-11-14 11 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()を動的仮想メソッドテーブルにそれを検索することによりDerived::fを呼び出すのに対し

​​

ようなコードにコール

base->Base::f(); 

静的基本メソッドBase::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()