0

I have a piece of code, that consists of an engine, a queue of pointers of requests processed by the engine, and a set of different types of requests, all of them classes - one 'most general' and a lot of variants.

Now, one of these request types requires a special handling.

class GenericRequest {};
class SpecificRequest1 : public GenericRequest {};
class SpecificRequest2 : public GenericRequest {};
class VerySpecialRequest : public GenericRequest {};

The queue just contains pointers (of type GenericRequest*) to instances. GenericRequest is instantiated too - instances of it appear in the queue too.

I need the engine to single out VerySpecialRequest and perform extra operations as it appears.

If I understood the answer involving inheritance in How to identify failed casts using dynamic_cast operator?, in my case using:

VerySpecialRequest* result = dynamic_cast<VerySpecialRequest*>( queue_entry );

if(result != NULL) { /* process the special entry */ }

will catch instances of GenericRequest on top VerySpecialRequest, only filtering off SpecificRequest1 and SpecificRequest2.

How can I go about identifying this specific child?

SF.
  • 13,549
  • 14
  • 71
  • 107
  • *"`GenericRequest` is not abstract"*, so you cannot use `dynamic_cast` on it. Make it polymorphic, and you would be able to do that (virtual destructor should suffice). – Jarod42 Jun 15 '18 at 12:09
  • @Jarod42 "abstract class". I don't think it means what you think it means. – n. m. could be an AI Jun 15 '18 at 12:10
  • @n.m.: From provided code, `class GenericRequest {};` -> no virtual methods. – Jarod42 Jun 15 '18 at 12:11
  • 1
    The *Right Way To Do Things*™ is to add a virtual function to `GenericRequest` and implement special handling in `VerySpecialRequest`. – n. m. could be an AI Jun 15 '18 at 12:12
  • @Jarod42: possibly. Been quite a while since I was learning that, probably forgot. Edited to make more clear what I meant. It does contain virtual methods, doesn't use them (the most generic usage pattern doesn't require them). – SF. Jun 15 '18 at 12:12
  • @Jarod42 provided "code" is not even syntactically correct as is. – n. m. could be an AI Jun 15 '18 at 12:14
  • @n.m. if you want full code, that's about 1300 LOC just of the engine and requests, not including invocations where requests are made and actually running the engine. I don't think this would be very helpful. I could include just some declarations from the original, but knowing this site, it would just yield a hundred irrelevant questions pertaining to inner workings of the engine and properties of the requests specific to business logic. – SF. Jun 15 '18 at 12:34
  • No, I'm happy with the code skeleton as is. – n. m. could be an AI Jun 15 '18 at 13:26

1 Answers1

2

I will change minimally your example code:

class GenericRequest {
   virtual ~GenericRequest;          // the virtual destructor makes GenericRequest polymorphic
};
class SpecificRequest1 : public GenericRequest {};
class SpecificRequest2 : public GenericRequest {};
class VerySpecialRequest : public GenericRequest {};

As soon as GenericRequest contains a virtual function, it becomes a polymorphic class, as become all of its subclasses.

Once polymorphism is ensured, we can safely use dynamic_cast:

GenericResult *queue_entry;
...
VerySpecialRequest* result = dynamic_cast<VerySpecialRequest*>( queue_entry );
if(result != NULL) { /* process the special entry */ }

That's all. Either queue_entry actually pointed to a VerySpecialRequest object, and result will point to that object, or it pointed to a non derived GenericResult, or a SpecificRequest1 or SpecificRequest2, and result will be a null pointer.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Thanks. I didn't notice the answer in the linked question never actually feeds a pointer to nstance of `A` to the `dynamic_cast` (nor ever instantiates `A` for that matter) so it in fact didn't answer my question at all. – SF. Jun 15 '18 at 13:25
  • @SF.: yes it did. The pointer is always a pointer to a polymorphic base class, and the dynamic cast converts it to a pointer to the subclass **if the pointer was obtained by converting an address/a pointer to the expected class. My answer is not much more than a rewording of the other one... – Serge Ballesta Jun 15 '18 at 13:29