Я использую шаблоны для реализации шаблона CRTP.С приведенным ниже кодом я получаю ошибки компоновщика (для всех методов, определенных в базовом классе CPConnectionBase
), например:
ошибка LNK2001: неразрешенный внешний символ "public: void __thiscall CPConnectionBase:: start (void) "(? start @? $ CPConnectionBase @ VTNCPConnection @@@@ QAEXXZ)
Полагаю, что решение здесь заключается в явной реализации шаблона.И действительно, я могу построить свой код, добавив
#include "TNCPConnection.h"
template class CPConnectionBase<TNCPConnection>;
в файл CPConnectionBase.cpp.Это, безусловно, неправильное место, поскольку я не хочу включать заголовок всех возможных производных классов в источник базового класса (я мог бы использовать базовый класс также в другом проекте с другими производными классами).
Поэтому моя цель - создать экземпляр шаблона в исходном файле производного класса (TNCPConnection.h или TNCPConnection.cpp), но я не смог найти решение.Добавление
template class CPConnectionBase<TNCPConnection>;
в файл TNCPConnection.cpp не решает мои проблемы с компоновщиком, а добавление
template<> class CPConnectionBase<TNCPConnection>;
в файл TNCPConnection.cpp дает мне ошибку времени компиляции:
ошибка C2908: явная специализация;'CPConnectionBase' уже был создан
Как можно избавиться от ошибок компоновщика, не делая реализацию базового класса зависимой от заголовочных файлов производных классов?
Здесьскелет моего кода:
CPConnectionBase.h
template <class Derived>
class CPConnectionBase : public boost::enable_shared_from_this<Derived>
{
public:
void start();
};
CPConnectionBase.cpp
#include "stdafx.h"
#include "CPConnectionBase.h"
template<class Derived>
void CPConnectionBase<Derived>::start()
{
...
}
TNCPConnection.h
#include "CPConnectionBase.h"
class TNCPConnection : public CPConnectionBase<TNCPConnection>
{
public:
void foo(void);
};
TNCPConnection.cpp
#include "stdafx.h"
#include "TNCPConnection.h"
void TNCPConnection::foo(void)
{
...
}