baseClass *array[10];
baseClass **array2 = new baseClass *[size];
This is the simplest and most dangerous way. You have to be careful about the lifetime of the objects in order to avoid leaking or double freeing. You also have to be careful with the array's allocation and deallocation, especially if you have to change the size at runtime.
std::vector<baseClass*> vec;
This improves the previous example because the vector handles the memory of the array for you, but you still have to be careful with the baseClass pointers.
std::vector<boost::variant<first,second> > vec2;
This is another improvement that eliminates the need to manually allocate or deallocate memory for the objects, and it's type safe in terms of accessing the objects as firsts or seconds. You can't mistake one kind of object for another.
std::vector<std::unique_ptr<baseClass>> vec3;
With this option you can still confuse objects of different types for each other, but it uses only the standard library and you still don't have to manage the lifetime of the objects you allocate. It does use C++11 though.
Also, if you don't need a dynamic array you can use std::array<...,size>
std::array<std::unique_ptr<baseClass>,10> array3;
has absolutely zero space or time overhead at runtime over baseClass *array[10];
, and is much safer. (zero overhead, assuming a decent implementation)