【问题标题】:Inherit from non-specialized template (shared library)从非专业模板继承(共享库)
【发布时间】:2018-01-22 13:06:55
【问题描述】:

当我直接从共享库类模板继承时,我得到“未解析的外部符号”,但如果我首先在我的代码中专门化库模板,它工作正常。

共享库中的模板类:

template <typename T>
class EventHandler
{
public:
    virtual ~EventHandler();
    virtual EventResult ReceiveEvent(T * evn, EventDispatcher<T> * dispatcher) = 0; 
};

我的代码中的派生类(没有专门化就无法工作):

class MyEventHandler : public EventHandler<SomeEventType>
{
public:
    virtual     EventResult    ReceiveEvent(SomeEventType * evn, EventDispatcher<SomeEventType> * dispatcher);
};

我的代码中的专用库模板类:

template <>
class EventHandler<SomeEventType>
{
public:
    virtual ~EventHandler() {}
    virtual EventResult ReceiveEvent(SomeEventType * evn, EventDispatcher<SomeEventType> * dispatcher) = 0;
};

我尝试直接在共享库的代码中复制它(我有源代码),它在没有模板专业化的情况下运行良好。它是否与 lib 无法访问完整的类实现有关?在这种情况下,EventHandler 模板在 .cpp 中没有任何附加定义,因为它只是一种纯虚方法。

如果重要的话,我的派生类也在命名空间内。

[EDIT] EventHandler 的类模板在 .cpp 文件中没有任何额外的实现,上面发布的 .h 文件中的这个定义就是它所做的一切(一个纯虚函数)。它与建议为可能重复的线程无关。

【问题讨论】:

标签: c++ templates inheritance linker shared-libraries


【解决方案1】:

原因是您的EventHandler 类中没有析构函数定义。您的专业化确实使它重载,因此编译器不会没有定义。请注意,这是必须在头文件中定义的代码,而不是在 cpp 文件中(因此,作为库二进制文件的一部分),因为编译器必须为 EventHandler 模板类型专用的每种类型实例化新定义/实例化。

【讨论】:

  • 但是如果我直接在共享库的代码中实现MyEventHandler,为什么它不需要专门化呢? EventHandler 的析构函数仍然没有定义,但是编译没有问题。
  • @ZaxFtw:使用您在此处提供的代码,我认为这是不可能的 - 例如,我猜测您的共享库将其定义意外隐藏在某个内部头文件中,它对 MyEventHandler 实现可见,但对库外部的代码不可见。这是 coliru 上的代码:coliru.stacked-crooked.com/a/a0929e3c490d918c
  • 在模板代码~EventHandler() {} 中添加了空的析构函数定义,但意外删除了= 0;,这使得函数不再是纯粹的,类不再是抽象的,并且由于某些未知的原因它不起作用。现在,当两者都返回(零和析构函数)时,它终于可以编译了。
猜你喜欢
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 2017-01-05
  • 1970-01-01
  • 2018-06-24
  • 1970-01-01
  • 2023-01-19
相关资源
最近更新 更多