Шаблон абстрактного класса C ++ + тип-специфичный подкласс = проблема с компоновщиком - PullRequest
0 голосов
/ 05 мая 2010

Данный проект касается различных конечных точек, взаимодействующих друг с другом. Конечная точка отправляет события (выходящие за рамки текущей проблемы) и может обрабатывать входящие события. Каждое событие представлено в общем объекте следующим образом:

#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.

Конечная точка определяется следующим образом:

#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>;

но не смог обойти вышеупомянутые ошибки компоновщика.

Любые идеи приветствуются.

Ответы [ 3 ]

3 голосов
/ 05 мая 2010

Шаблоны функций и функции-члены шаблонов классов должны быть реализованы в заголовочных файлах, а не в файлах .cpp. Я полагаю, у вас Event<T>::Event() реализован в файле .cpp?

0 голосов
/ 05 мая 2010

Я только что нашел решение. Хотите верьте, хотите нет, но он отлично связывается с v2.20 компоновщика GNU (ld), но не с ld 2.19.

Кстати

#pragma interface 

и

#pragma implementation

- это обходной путь, специфичный для g ++, решающий проблему реализации шаблонных классов в заголовочных файлах. С помощью тегов прагмы этого можно избежать, так что это не проблема, но все равно спасибо за ваши предложения.

0 голосов
/ 05 мая 2010

Как отметил sbi, запрещается разделять интерфейс и реализацию шаблонов в файлах исходного кода и заголовочных файлов. Проверьте эту ссылку для деталей (конец страницы) http://www.cplusplus.com/doc/tutorial/templates/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...