Gianfranco Damato
Gianfranco Damato

Reputation: 1

Casting to subclass from a collection of base pointers

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

Answers (1)

Akshay Rao
Akshay Rao

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

Related Questions