【问题标题】:C++ abstract class template + type-specific subclass = trouble with linkerC++ 抽象类模板 + 特定类型的子类 = 链接器有问题
【发布时间】:2010-05-05 10:18:52
【问题描述】:

有问题的项目是关于相互通信的不同端点。端点发送事件(超出当前问题的范围)并且可以处理传入事件。每个事件在一个通用对象中表示如下:

#pragma interface
... // some includes

template<typename T>
class Event
{
   public:
                       Event(int senderId, Type type, T payload); // Type is an enum
                       Event(int senderId, Type type, int priority, T payload);
      virtual          ~Event();
      virtual int      getSenderId();
      virtual int      getPriority();
      virtual T        getPayload();
      void             setPriority(const int priority);

   protected:
      const int        senderId;
      const Type       type;
      const T          payload;
      int              priority;
};

它的实现类带有#pragma implementation 标签。

端点定义如下:

#pragma interface
#include "Event.h"

template<typename T>
class AbstractEndPoint
{
   public:
                        AbstractEndPoint(int id);
      virtual           ~AbstractEndPoint();
      virtual int       getId();
      virtual void      processEvent(Event<T> event) = 0;    

   protected:
      const int         id;
};

它也有自己的实现类,但只定义了构造函数、析构函数和getId()。

这个想法是为每种不同的有效负载类型创建具体的端点。因此,我对每种类型都有不同的有效负载对象和特定的事件类,例如

Event<TelegramFormatA>, Event<TelegramFormatB>

ConcreteEndPoint for TelegramFormatA, 
ConcreteEndPoint for TelegramFormatB

分别。后面的类被定义为

class ConcreteEndPoint : AbstractEndPoint<TelegramFormatA>
{
    ...
}

我正在使用 g++ 4.4.3 和 ld 2.19。一切都编译得很好,但是链接器抱怨未定义对特定类型事件类的引用,例如

Event<TelegramFormatA>::Event(....) .

我尝试使用显式实例化

template class AbstractEndPoint<TelegramFormatA>;

但无法克服上述链接器错误。

任何想法都将不胜感激。

【问题讨论】:

    标签: c++ inheritance templates


    【解决方案1】:

    类模板的函数模板和成员函数必须在头文件中实现,而不是 .cpp 文件。我想您在 .cpp 文件中实现了Event&lt;T&gt;::Event()

    【讨论】:

      【解决方案2】:

      正如 sbi 已经指出的那样,不允许在源文件和头文件中分离模板的接口和实现。查看此链接了解详情(页尾)http://www.cplusplus.com/doc/tutorial/templates/

      【讨论】:

      • 允许在 .cpp 文件中包含实现,但必须在头文件中#included 以便实现可见。它也不能自己编译。当它以这种方式组织时,通常会使用不同的文件扩展名(通常是 .inc)。
      【解决方案3】:

      我刚刚找到了解决方案。信不信由你,它与 GNU 链接器 (ld) 的 v2.20 完美链接,但无法与 ld 2.19 链接。

      顺便说一句

      #pragma interface 
      

      #pragma implementation
      

      是一种特定于 g++ 的解决方法,用于解决在头文件中实现模板类的问题。使用编译指示标签可以避免它,所以这不是问题,但无论如何感谢您的建议。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-12
        • 1970-01-01
        • 2013-10-06
        相关资源
        最近更新 更多