A
A
awetlux2016-01-19 08:01:37
C++ / C#
awetlux, 2016-01-19 08:01:37

Polymorphism in C++ and how to implement it correctly using a pointer to void?

The description of the question is voluminous, but it is most likely simple. Its essence is as follows:
We have an interface class, a base class, two successor classes of the base class. In the interface, we also have a virtual function for displaying information, which is "specified" in the descendant classes.

//класс интерфейс
class InterfaceClass{ 
public:
InterfaceClass();
~InterfaceClass();
virtual void output() = 0;
}
//базовый
class Base : public InterfaceClass{
public:
//тут нужные конструкторы
void output(); //выводим a
protected:
int a;
};
//производный
class DerivateOne : public Base{
public:
//тут конструкторы
void output(); //выводим b1 и a
protected:
int b1;
};
//производный
class DerivateTwo : public Base{
public:
//тут конструкторы
void output(); //выводим b2 и a
protected:
int b2;
}

Next, we want to create an array of objects of type DerivateOne and DerivateTwo directly in main():
...
DerivateOne ArrOne[3]; //массив типа DerivateOne
DerivateTwo ArrTwo[3]; //массив типа DerivateTwo
//инициализируем элементы массива
...

And, in fact, the question itself. Let's say we have a pointer to void:
void *ptr;
How to traverse the array using this very pointer and address arithmetic, namely increment (ptr++)?
That is, instead of:
for (int i = 0; i < 3; i++){
ArrOne[i].output();

Write something like:
ptr = &ArrOne[0]
for (int i = 0; i < 3; i++){
ptr->output();
ptr++;
}

And, accordingly, after that ptr will point to the elements of the ArrTwo array.
Is it necessary to cast void *ptr to an interface type (InterfaceClass*), and only then operations like ptr++ and similar actions with output become available?
Thanks for reading =)

Answer the question

In order to leave comments, you need to log in

4 answer(s)
A
AtomKrieg, 2016-01-19
@AtomKrieg

If the array contains the classes themselves, and not pointers to them, then there will be an incorrectness if the sizes of the classes differ (sizeoff) - for example, a different number of class members. It's better to do this:

vector<Base*> v;
v.push_back(new DerivateOne);
v.push_back(new DerivateTwo);
for(auto b: v)
    b->output();

A
Armenian Radio, 2016-01-19
@gbg

You don't have to play around with C++ C.
The compiler is not so dumb as not to replace the index operator with a pointer. But you will turn the code into slop.
void* in C++ is the same rubbish. This is what interfaces are for. Let the compiler and optimizer do the work.

R
RedHairOnMyHead, 2016-01-19
@ThePyzhov

The pointer must be to the base class, then what you wrote at the very bottom should work.

A
Alexander Titov, 2016-01-19
@alex-t

1. Well, once again, otherwise it is not obvious somewhere in the comments. The ++ operator for the pointer must shift by the size of the object. Therefore, 100% will work correctly only on a specific inherited class. And on the basic ones, especially the interface ones, if you are "very lucky".
2. It is not clear from the example why you need to use a void pointer instead of an array iterator.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question