How to pass "Any kind of data" function in C ++

Suppose I have a class handler with some subclasses, such as a handler, SomeTypeHandler, AnotherTypeHandler. The class handler defines the descriptor method as a common interface for all subclasses. The logic of "process", of course, is completely different for different handlers.

So what I need to do is pass the value of any descriptor method. Certain classes can then drop "whatever" to the type they expect.

Basically what I need is something like a Java Object: D class

The first thing I tried was void* , but apparently you can't do B* someB = dynamic_cast<B*>(theVoidPointer) , so you're out of luck.

My second idea was to use boost::any . however, the requirement to use boost :: any is that the value should be copied, but this does not apply to my data.

Any ideas to make this work?

thanks

EDIT: Notice that I know that I can use the SomeData class without any members, and let my data be subclasses of this, but I'm looking for a more general approach that does not require me to create my own wrapper class.

+6
source share
5 answers

Ok, here is a simple approach using boost :: any to hold pointers to your data types. However, be careful that boost :: any adds some utility code that slightly reduces performance (in most cases, negligible). Use boost :: spirit :: hold_any or void * instead if you don't need type safety.

 class Handler { public: void handle( boost::any value ) { do_handle( value ); } private: virtual void do_handle( boost::any& value ) = 0; }; template<class T> class HandlerBase : public Handler { private: void do_handle( boost::any& value ) { // here you should check if value holds type T*... handle_type( *(boost::any_cast<T*>( value )) ); } void handle_type( const T& value ) = 0; }; class StringHandler : HandlerBase<std::string> { private: void handle_type( const std::string& value ) { // do stuff } }; 

Now you can write many handler classes, getting from HandlerBase, without assuming that the processed types have a common base class.

+1
source

You can, for example, define a base class:

 class BaseHandlerData { ... }; 

Then output your specific data classes that are expected by your handlers:

 class StringData: public BaseHandlerData { ... }; class SomeData: public BaseHandlerData { ... }; 

Then you should be able to pass the BaseHandlerData * argument to the handle method and use something like:

 void handle(BaseHandlerData *data) { StringData* stringData = dynamic_cast<StringData*>(...); // handle your string data here ... } 

to use your expected data type safely.

Herald

+1
source

Another alternative, closer to C , would be union ( http://en.wikipedia.org/wiki/Union_ (computer_science) # C.2FC.2B.2B ). This will allow you to pass only the types that you specify, not any type, but have the type of behavior that you describe.

+1
source

Do you need a DataObject base class or something like that. All of your data types (string, number, and more) are subclasses of DataObject. You define Handle as follows:

 void Handle(DataObject *dataObject); 

This is a much safer way to do what you want. To do this even better, a DataObject may even know what data it contains. Handlers can then verify that the correct data type was sent to them.

0
source

You can do

 B* someB = static_cast<B*>(theVoidPointer); 
-1
source

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


All Articles