virtual constructor ideom with templates

C

Christof Warlich

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 T> class 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 T> class SomeServiceImplementation: public
SomeService<T> {
public:
void useService(T t) {
// do something useful
}
};
template<typename T> SomeService<T> *SomeService<T>::create(void) {
return new SomeServiceImplementation<T>;
};
// ServiceImplementation.cc ends
 
V

Victor Bazarov

Christof said:
[..link error with templates..]
This is because the compiler does not see the implementation
(template) of SomeService<T>::create() [..]

Is there any way to work arround this, [..]

This is covered in the FAQ.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top