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
    You can create an array of pointers to the common parent of your classes (inclusion polymorphism, 'is a' relation). Of course, with the help of a crowbar (sishny cast) you can cram a variety of pointers into one array, but it’s better not to do so. A perversion, very stupid and dangerous. - alexlz
  • And you can do something like this: class A {... class B: public A {} obj_b; } a; ? Of course, this is still the perversion))), but still ... I did not succeed ... - Alerr
  • one
    @alexlz: why caste? ideone.com/fYJgi3 - VladD
  • @VladD Firstly there is a cast there, albeit implicit. Secondly, there is a reduction of the type-descendant to the type-parent. I wrote about casting to a pointer to a foreign type (i.e. B is not an heir of A). Sishny cast will do this without sound. (But you shouldn't do that) - alexlz
  • one
    @alexlz: well, there is an implicit cast, which is even weaker than static_cast , and not at all evil (yet B is A ). To lead to a pointer to an unrelated type, of course, is not worth it, I agree to 200%. - VladD

2 answers 2

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.

  • one
    Python 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
  • four
    Your 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