The usual way to create a pointer that can point to either of the two is to make them inherit from a common base-class. Any pointer of the base-class can point to any sub-class. Note that this way you can only access elements that are part of the base-class through that pointer:
class Base {
public:
int a;
};
class Sub1 : public Base {
public:
int b;
};
class Sub2 : public Base {
public:
int c;
};
int main() {
Base* p = new Sub1;
p.a = 1; // legal
p.b = 1; // illegal, cannot access members of sub-class
p = new Sub2; // can point to any subclass
}
What you are trying to achieve is called polymorphism, and it is one of the fundamental concepts of object oriented programming. One way to access member of the subclass is to downcast the pointer. When you do this, you have to make sure that you cast it to the correct type:
static_cast<Sub1*>(p).b = 1; // legal, p actually points to a Sub1
static_cast<Sub2*>(p).c = 1; // illegal, p actually points to a Sub1
As for your second question, using the technique described above, you can create a set of pointers to a base-class which can then hold instance of any of the subclasses (these can also be mixed):
std::set<Base*> base_set;
base_set.insert(new Sub1);
base_set.insert(new Sub2);