0
#include <iostream>
#include <ostream>
using namespace std;

enum Month
{
    jan = 1,
    feb,
    mar
};

class Show
{
public:
    virtual void Display() = 0;
};

class Date : public Show
{
private:
    Month m;
    int day;
    int year;
public:
    Date( Month mName, int dayName, int yearName )
    {
        m = mName;
        day = dayName;
        year = yearName;
    }
    void Display()
    {
        cout << this->m << endl;
    }
};

void displayData( void *data[] )
{
    Month m = *( reinterpret_cast<const Month*> ( data[ 0 ] ) );
    cout << m << endl;
}

int main( int argc, char**argv )
{
    Date d1( jan, 28, 2017 );
    void * data[ 1 ];
    data[ 0 ] = &d1;
    displayData( data );
    return 0;
}

I'm getting the correct value for Month m in the function void displayData but when I inherit the Date class from the abstract class Show, then I'm getting a garbage value for Month m. Can anyone tell me why is this happening ?

zett42
  • 25,437
  • 3
  • 35
  • 72
Napada
  • 1
  • 1
  • 1
    The derived class has a table of pointers to virtual functions that it seems is placed in the beginning of the class. – Vlad from Moscow Jun 10 '17 at 13:56
  • 1
    Not to mention the bad type cast is to something completely unrelated, so inheritance has nothing to do with this. Did you want something like https://stackoverflow.com/questions/670734/c-pointer-to-class-data-member ? Or just use d1.m – Kenny Ostrom Jun 10 '17 at 14:05
  • Thanks for your reply. Is there a way around for this ? – Napada Jun 10 '17 at 14:07
  • Why bother defining all these types if you're going to strip them away with the `void*` casting? Surely `displayData` should at least take a `Show` parameter? Anyway, you're forcing it to interpret a `Date` as a `Month` so you will probably just get garbage. – gavinb Jun 10 '17 at 14:09
  • In that data array I can have other objects of different class, so I'm casting it to void *. I'm forcing Date to interpret as Month so as to get the Month value and proceed further depending on the month value. Is there any other way to accomplish this ? – Napada Jun 10 '17 at 14:37

2 Answers2

2

You are reinterpret-casting a Date as a Month. So, you are assuming that this is a safe conversion, but it isn't. It happens to work purely by accident when the Date class is just plain data, but when you derive the Date class from Show then the structure of the class becomes more complicated, and the accident does not hold true anymore.

What is probably happening is that the first element in Date is now a pointer to the virtual method table of the class rather than the first member declared in the class.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
0

You should not use the void pointer. Use a base class like Show instead, like:

void displayData( Show *data[] )
{
    data[0]->Display();
}

int main( int argc, char**argv )
{
    Date d1( jan, 28, 2017 );
    Show* data[ 1 ];
    data[ 0 ] = &d1;
    displayData( data );
    return 0;
}

Else how you would devide the void pointers to their classes?

Tobias Wollgam
  • 761
  • 2
  • 8
  • 25