2016-11-14 3 views
0

Мне удалось избавиться от ошибки неоднозначности при использовании перегруженных функций от нескольких родителей, используя шаблон с родительским разрешением, но это дает ошибку компоновщика при поиске AddObjectImpl, что странно, поскольку эта функция является виртуальной ,C++ multiple template pure virtual inheritance

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), чтобы вызвать правильный виртуальный метод.

В коде, как

class Base { 
    public: 
    virtual void f(); 
}; 
class Derived : public Base { 
    public: 
    virtual void f(); 
}; 

Base* base = new Derived; 

Вызов

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()

 Смежные вопросы

  • Нет связанных вопросов^_^