Reputation: 1
I need to model a service retriever class to retrieve various services.
Suppose you have a collection of Services, each Service retrievable with a unique string key
(eg. : Services.getService("render");
should retrieve the service indexed as "render").
Now, Service
is the base class of various *Service inherited classes, like RenderService, InputService et al. , each one with their different methods.
Now, this could be simply modeled with a std::unordered_map<std::string, Service*>
, but it returns a pointer to the base class and not to the derived class (so far, it's pretty obvious). This means I can't automatically call the requested service's methods without doing an explicit cast, I must write something like: ((RenderService*)Services.at("render"))->callRenderServiceMethod();
.
This is pretty ugly and redundant, because the at
method key is logically linked to RenderService
.
I could skirt around the problem by declaring:
#define CALL_RENDER ((RenderService*)Services.at("render"))
and using it as
CALL_RENDER->callRenderServiceMethod();
Although it looks like a clever "hack", it's not the right way to solve this problem.
I've also tried to do something like getService<RenderService>("render");
but it doesnt work well and the redundancy problem is still there.
In the end, I'm doing this because I'd like to avoid this :
class Services
{
public:
RenderService& getRenderService();
AudioService& getAudioService();
AnotherInheritedService& getAnotherInheritedService();
private:
RenderService _renderService;
AudioService _audioService;
AnotherInheritedService _anotherInheritedService;
};
What kind of approach should I use for this kind of problem?
Upvotes: 0
Views: 94
Reputation: 342
From what I understand from the problem, you need the functions to be declared as virtual functions.
Declaring a function virtual in the base class definition and implementing that function in each derived class will allow the appropriate class' function to be called based on the type of class pointer.
Now, I don't understand why you only have pointers to the base class only. Logically, the pointers you're getting from unordered_map
are being returned should be actually derived class pointers but only being "upcasted" to a base class pointer.
Upvotes: 1