Good evening! Has anyone done something like this? I created an array of pointers void *pointer[10];
and did so pointer[0]=&ob1; pointer[1]=&ob2;... где ob1, ob2..
pointer[0]=&ob1; pointer[1]=&ob2;... где ob1, ob2..
are objects of different classes ... The task is to access the fields and methods of the classes through the pointers to the objects they refer to. For example, pointer[0]->ob1_func();
Call the method of the first object. How to do it? Tried on everyone, does not work.
2 answers
You can store not just pointers in the array, but "half-witted pointers". These pointers will be the usual class, which will consist of two fields - the actual pointer to the object and the number that will identify the type of the object.
struct hspointer { // half-smart pointer void * pointer; int type; };
But the problem arises - how to call functions on an object? You can certainly make tons of castes, but this is not an option. To do this, we will add a new function to this class - bool call(std::string func)
. Inside this function, we will check the type of the object and the string-name and call the desired function of the desired object. At the very beginning, this can all be done on the basis of case + case/if
, but it can also be done on the basis of std::map
(which, with a large number of types and functions, will increase and simplicity). Here is an example implementation.
If the implementation allows, then each class can contain its own map with a list of its methods.
Pros:
- each object manages its functions, fully controls them.
- Called functions can be private.
- In case the function is not found, the object can call its own personal one.
Minuses:
- it is desirable to inherit objects from one common ancestor, so that the call function does not make permanent castes.
The second way is that the objects do not change at all, but the call
function does all the rough work.
It remains to solve a few minor problems - what to do with the arguments and the returned result. Actually the arguments can be referred to as Variable Argument Lists . And the result can be the second argument. That is, the call
method will be as follows:
bool call(std::string method, ...) { func = getFuncPointerByName(method); if (func == NULL) return false; va_list arguments; va_start ( arguments, method ); func(arguments); // здесь можно навернуть различную магию. va_end(arguments); return true; }
But still not really want to call through a separate method. Therefore, you can overload the operator()
statement. In general, there is a lot of work, but the result will be an interesting solution. But ask yourself, do you really need this? Maybe it will be faster to scatter objects on two or three types, make base classes for them, which will contain all the necessary functions and just have two or three lists instead of one.
- onePython in C ++ - skegg
- something like that. I remembered about python myself when I composed it :) - KoVadim
Here is an example of how this can be done: http://ideone.com/UNOkpj . But is it necessary? The fact that C ++ allows you to do this does not mean that it is worth doing so. I can not imagine where this can be used. Reconsider the logic of your application, something is wrong with it. To push heterogeneous objects into one array is unnatural.
- Well, this, for me, does not make sense, because ((A *) (p [0])) -> a; If it were p [0] -> a, it would make sense ... - Alerr
- fourYour p [0] -> a does not make sense for the compiler. How does he, in your opinion, know which object of the class lies by the pointer p [0]? After all in rantayme you can write down anything there. A C ++ program is compiled into machine code, in which even the very notion of "class" does not make sense. There is just a section of memory that the program refers to. And the machine does not know what the data type is at the address p [0]. Explicit caste at the compilation stage indicates how to perceive a particular section of memory, but it is impossible to rotate it at runtime. - fori1ton
static_cast
, and not at all evil (yetB
isA
). To lead to a pointer to an unrelated type, of course, is not worth it, I agree to 200%. - VladD