テンプレート化された基本クラスを使用し、それを継承して Service Locator パターンを実装しようとしています。
// Header File
namespace one {
template <class I, class N>
class Locator {
public:
static void initialize() {
service = &nullService;
}
static void provide(I* newService) {
if (newService == 0) {
initialize();
} else {
service = newService;
}
static I& get() { return *service; }
virtual ~Locator() {
if (service != &nullService) {
delete service;
}
private:
Locator();
static I* service;
static N nullService;
};
}
// Source File
#include "Locator.hpp"
namespace one {
template<class I, class N>
I* Locator<I, N>::service;
template<class I, class N>
N Locator<I, N>::nullService;
}
クラス Iはインスタンス クラスで、クラス Nはヌル サービス クラスです。派生クラスの場合:
// Header File
namespace two {
class ExampleLocator : public one::Locator<Service, NullService> {}
}
// Source File
namespace one {
template class Locator<Service, NullService>;
}
この実装を試してみると、
int main(int argc, char const *argv[]) {
two::ExampleLocator::initialize();
two::ExampleLocator::get().doSomething();
}
gcc は次のエラーでコンパイルに失敗します:
- one::Locator::initialize() への未定義の参照
- 関数 one::Locator::get() 内: one::Locator::service への未定義の参照
私は何を間違っていますか?
注: 派生クラスの cpp で Locator の静的プロパティを再宣言することで、プロジェクトをコンパイルできます。
// Alternative Derived class Source file
namespace one {
template<class I, class N>
I* Locator<I, N>::service;
template<class I, class N>
N Locator<I, N>::nullService;
template class Locator<Service, NullService>;
}
注 2: Derived クラスは、Locator クラスとは異なる名前空間にあります。