tags:

views:

166

answers:

4

Hi,

How can i create an array which can hold objects of different classes in C++.

+10  A: 

You can use boost::any or boost::variant (comparing between the two: [1]).

Alternatively, if the "objects of different classes" have a common ancestor (say, Base), you could use a std::vector<Base*> (or std::vector<std::tr1::shared_ptr<Base> >), and cast the result to Derived* when you need it.

KennyTM
There is also boost:variant. But I wouldn't recommend this approach unless you really want to hold objects of unrelated classes. Otherwise option 2 is probably better.
f4
I would recommend `Variant` over `Any` if the collection is known. Static check is a huge appeal. It's also a faster, which is a nice bonus.
Matthieu M.
+1  A: 

define an base class and derive all your classes from this.

Then you could create a list of type(base*) and it could contain any object of Base type or derived type

SysAdmin
It needs to be pointers to the base class (or at least some kind of reference), otherwise you will slice the objects to the base.
Skurmedel
@Skurmedel - obviously it needs to be a pointer. who would think of putting it as values?...anyway I will edit my answer
SysAdmin
I would 2 years ago :)
Skurmedel
Is it not possible that that array be of void * type and hold the objects, likevoid objectsList[] = {object1, object2, object3,nil};
iSight
@iSight: It is, but then how would you delete the objects or even know what they are? The point is, you need to have some interface common to all objects in the array or objects need to have RTTI (normally any virtual function will give that) so you can `dynamic_cast` pointers.
doublep
@doublep Ok thanks for this suggestion, i need to inherit from one common class which has virtual function which returns class name where it will be implemented in all the classes inheriting from the base class. Then, after type casting to Base class and calling the function which returns name of the respective subclasses, i can then convert it into corresponding subclass type. Will this work out....
iSight
@iSight - you dont need a function which returns an ID or name. as doublep mentioned use RTTI. there is a typeid operator to get the type of an object. just google it..
SysAdmin
@SysAdmin thanks for this suggestion
iSight
+2  A: 

Have a look at boost::fusion which is an stl-replica, but with the ability to store different data types in containers

Viktor Sehr
+1  A: 

If you want to create your own, wrap access to a pointer/array using templates and operator overloading. Below is a small example:

#include <iostream>

using namespace std;

template <class T>
class Array
{
private:
    T* things;

public:

    Array(T* a, int n) {
        things = new T[n];
        for (int i=0; i<n; i++) {
            things[i] = a[i];
        }
    }

    ~Array() {
        delete[] things;
    }

    T& operator [](const int idx) const {
        return things[idx];
    }
};

int main()
{    
    int a[] = {1,2,3};
    double b[] = {1.2, 3.5, 6.0};

    Array<int> intArray(a, 3);
    Array<double> doubleArray(b, 3);

    cout << "intArray[1]: " << intArray[1] << endl;
}
Nils
However this only holds one type per instance. I'm not sure how to implement a container which can store different data types in one instance. Maybe by using function templates somehow?
Nils