Hi all,
I'm using the virtual constructor ideom to hide implementation details
of services from an application that uses these services, i.e.:
// serviceInterface.h
class SomeService {
public:
static SomeService *create(void);
virtual void useService(void) = 0;
};
// serviceInterface.h ends
// application.cc
#include "serviceInterface.h"
int main(void) {
SomeService *someService = SomeService::create();
someService->useService();
return 0;
}
// application.cc ends
// serviceImplementation.cc
#include "serviceInterface.h"
// numerous implementation specific include files may be needed here
class SomeServiceImplementation: public SomeService {
public:
void useService(void) {
// do something useful
}
private:
// numerous implementation specific types may be needed here
};
SomeService *SomeService::create(void) {
return new SomeServiceImplementation;
};
// serviceImplementation.cc ends
This works pretty well, avoiding that the compiler of the application
needs to know the include paths of all the files that the service
implememtation may need.
But when I want to offer a service with templates (see slightly modified
example below), this approach doesn't seem to work any longer: It
compiles and links fine as long as everything is put into a single file,
but if I do the file split as suggested, the compiler says:
In function `main':application.cc: undefined reference to
`SomeService<int>::create()'
This is because the compiler does not see the implementation (template)
of SomeService<T>::create() when it needs to instantiate it for type
int. Ok, I know that the template implementation has to be put into the
header file as well for this very reason, but if I put it into
serviceInterface.h, I also have to put the class definition of class
SomeServiceImplementation there, which would finally destroy the
"virtual constructor ideom" I'd liked to implement.
Is there any way to work arround this, keeping both the application and
the service implementation independent from each other, at best only
connected through the interface definition that the application is
supposed to be used? I'm desperate, because this independency was a
fundamental design goal of the services being offered.
Thanks for any help,
Christof
// serviceInterface.h
template<typename Tclass SomeService {
public:
static SomeService<T*create(void);
virtual void useService(T t) = 0;
};
// serviceInterface.h ends
// application.cc
#include "serviceInterface.h"
int main(void) {
SomeService<int*someService = SomeService<int>::create();
someService->useService(10);
return 0;
}
// application.cc ends
// serviceImplementation.cc
#include "serviceInterface.h"
template<typename Tclass SomeServiceImplementation: public
SomeService<T{
public:
void useService(T t) {
// do something useful
}
};
template<typename TSomeService<T*SomeService<T>::create(void) {
return new SomeServiceImplementation<T>;
};
// ServiceImplementation.cc ends