C ++ dual submission with mirror hierarchies

The following class hierarchies are an abstract resource handler and resource hierarchy. Both interfaces have base classes. Now imagine that you are writing a system in which you can implement several specific resource systems under these interfaces. Here is just one example. A particular main class creates resources derived from material. Now, when the created resource is passed to the base interface, it is passed as a pointer to the base resource class, but I want to process a specific resource and have access to its specific attributes.

I know about double dispatch, but I don't think this works in this case. I would like to prevent RTTI and dynamic_casts. Do you have any suggestions for handling such cases?

class resource; class main_resource_handler { public: virtual resource* create_resource() = 0; virtual void do_some(resource* st) = 0; }; class resource { }; class specific_resource : public resource { public: int i; }; class specific_resource_handler : public main_resource_handler { public: stuff* create_resource) { return new specific_resource); } void do_some(resource* st) { // in here i want to work with specific resource } void do_some(specific_resource* st) { // i want to get here } } main_resource_handler* handler = new specific_resource_handler(); resource* res = handler->create_resource(); handler->do_some(res); /// here 
+4
source share
4 answers

I think you will not ask the right question.

To do what you ask, you need to add the following:

 template<typename T> class helper : public main_resource_handler { public: virtual resource* create_resource() { return new T; } virtual void do_some(resource* st) { do_some_specific(static_cast<T*>(st)); } private: virtual void do_some_specific(T* st) = 0; }; 

And change this:

 class specific_resource_handler : public helper<specific_resource> { private: virtual void do_some_specific(T* st) { ... } } 

static_cast is safe if you can guarantee that you will always call do_some in the right type of handler. But if you already know that this is the correct type of handler, then there is no need to make a call to the base class method. Therefore, presumably, you want to get some resource , not knowing its exact type, and pass it to the appropriate handler. This is harder ...

+1
source

I wonder if what you are looking for is a curiously repeating pattern template . There is fooobar.com/questions/70183 / ....

0
source

I'm not sure why you need both a resource and a handler - it seems you are exposing an additional connection with something that would be encapsulated. The problem will not exist if the created resource simply returned a resource that the client could call methods directly.

If you need security, specify the resource, remember the address of the handler that created it, then check that in do_some(resource* st) . If the resource was created by the current handler, and the handler can only create resources of a certain type, then it is safe to enable it and call a specific function. Although, as above, if a function was only a virtual function on a resource, it would by definition be a safe type.

0
source

Source: https://habr.com/ru/post/1302673/


All Articles