2010-05-05 3 views
0

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

#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

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

0

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

+0

Разрешено иметь реализацию в формате .cpp, но затем она должна быть включена в заголовочный файл, чтобы реализация была видимой. Он не должен компилироваться сам по себе. Когда он организован таким образом, обычно используется другое расширение файла (обычно .inc). –

0

Я только что нашел решение. Верьте или нет, он отлично связывается с v2.20 GNU linker (ld), но не делает этого с ld 2.19.

Кстати

#pragma interface 

и

#pragma implementation 

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

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