Search code examples
c++arraysooppointersdowncast

to downcast elements from parent class


I am doing computer assignment with OpenGL

But I am new of c++. It is very different with Java.

here's I tried.

class Map {
private :
public :
    short mapkind;
    float a = 5;
    Map() 
    {}

};

class Road : public Map {
private :
public :    
    Road()
    {
        mapkind = 0;
    }
};

class Glass : public Map {
private:
public:
    float color[3] = { 0.0, 1.0, 0.0};

    Glass()
    {
        mapkind = 1;
    }
};

And then I made array.

Map* maps[10] = { new Road(),
   new Glass(), 
   new Road(), 
   new Glass(), 
   new Glass(), 
   new Road(), 
   new Road(), 
   new Glass(), 
   new Road(), 
   new Glass() };

And this is in my main loop.

for (int i = 0; i < 10; i++) {
if ((*maps)[i].mapkind == 0) {
    //draw road
    Road* temp;
    temp = (Road*)maps[i];
}
else if ((*maps)[i].mapkind == 1) {
    //draw glass
    Glass* temp;
    temp = (Glass*)maps[i];
}
else {
    //exit(4);
    printf("error %hd %d \n", (*maps)[i].mapkind);
}
}

I learned C and pointer But It's too old. I guess that In Array, putting 'new Class()' as one element would be wrong, But I don't know how to fix it.

first number is short type %hd and second one is int type %d for printing short type variable 'mapkind'

first number is short type %hd and second one is int type %d for printing short type variable 'mapkind'


Solution

  • The problem here is not the casting, it's how you dereference the array:

    (*maps)[i].mapkind
    

    This first dereferences maps (which gives you maps[0]) and then you use that pointer as an array, which it is not. This leads to undefined behavior.

    Instead do maps[i]->mapkind (or if you want to use explicit dereferencing and dot-syntax (*(maps[i])).mapkind).


    Also, you should "unlearn" C-style casting when programming in C++, it can lead to trouble when you least expect it. Instead use e.g. static_cast:

    Glass* temp = static_cast<Glass*>(maps[i]);
    

    Or like I mentioned in my comment, use virtual functions which will be called in the correct object using the correct class.