Vijay
Vijay

Reputation: 67251

Store objects of three different classes in an array

This is an interview question: how can we store the objects of let's say 3 different classes which are totally independent of each other.

My answer was: create an array which stores all void pointers. like :

void *array[];

and store the pointers of all the objects.the array elements can be many. but for retrieving the elements,i said we can use the dynamic cast or the static cast! this i think is the wrong answer.i think dynamic cast and static cast are supposed to be used among the classes which are dependent. please correct me if i am wrong.

if dynamic cast and static cast doesn't work.May be we can use reinterpret cast.

but is this the correct way to do this task?

Upvotes: 0

Views: 1097

Answers (4)

James Kanze
James Kanze

Reputation: 153929

The only "correct" way to do this is to use something like boost::variant. If you cannot use boost, then you have to more less do the same thing: implement a discriminate union which accepts all of the desired types. This isn't as hard as it might seem: for POD types, you can just use a normal union for the data; for non-POD types, you add a unsigned char x[sizeof(T)] to the union, and use placement new and explicit delete on it, as needed. And you add whatever is necessary to the union to ensure alignment. Thus, for a user type MyClass and a double, one might have something like:

class MyVariant
{
public:
    enum Type { t_double, t_MyClass };
private:
    Type m_type;
    union
    {
        double m_double;
        unsigned char m_MyClass[sizeof(MyClass)];
        MaxAlignFor<MyClass> m_dummyForAlignment_MyClass;
    };
public:
    MyVariant( double d )
        : m_type( t_double )
    {
        m_double = d;
    }
    MyVariant( MyClass const& c )
        : m_type( t_MyClass )
    {
        new (m_MyClass) MyClass( c );
    }
    ~MyVariant()
    {
        switch ( m_type )
        {
        case t_double:
            break;

        case t_MyClass:
            reinterpret_cast<MyClass*>( m_MyClass )->~MyClass();
            break;
        }
    }
};

And so on. (There's obviously a lot more involved, but this should give the basic framework.)

Upvotes: 1

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385204

Why are you trying to make this so complicated?

struct T {
   T1 obj1;
   T2 obj2;
   T3 obj3;
};

If you instead mean that you have an array of objects, and each element can be of any of three distinct, unrelated types, then it's a silly interview question because it's a silly thing to do.

(Yes, you would consider reinterpret_cast if forced to employ this approach by limited job opportunities and a pressing need to consume food.)

Upvotes: 5

n. m. could be an AI
n. m. could be an AI

Reputation: 119887

dynamic_cast from void* is not allowed, you need a polymorphic pointer for that (that is, a pointer to a class with a virtual method in it).

You cannot use other casts because the target type of the cast is not known. Once you cast a typed pointer to void*, the type information is lost forever. Given just the pointer, you have no chance to get that type information back. You need to remember something about the type somewhere in some form. How about enum { one, two, three } alongside the void* ?

Upvotes: 1

Tony The Lion
Tony The Lion

Reputation: 63220

You could use a boost::variant<myfoo, anotherfoo, somefoo> v to put into a vector<v> and then you can store one class per item in the vector, however it can store variables of all three types.

You can find more info on boost::variant here

Upvotes: 3

Related Questions