C ++多模板纯虚拟继承

时间:2016-11-14 17:19:43

标签: c++ inheritance linker

通过使用带有父分辨率的模板,在使用多个父项的重载函数时,我设法摆脱了歧义错误,但是在查找AddObjectImpl时会出现链接器错误,这很奇怪,因为该函数是虚拟的。

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 个答案:

答案 0 :(得分: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()

编译器编译它,即使它可以推断它是对纯虚方法的静态调用。最后,链接器抱怨错误消息body { margin: 0px; /* optional */ } #box { position:absolute; height: 100%; min-width: 100%; } .page { padding: 5px; /* optional */ height: inherit; }