The advantage of using pointers to base classes comes when you have virtual functions.
 Imagine the following
class A {
    A(){}
    virtual ~A(){} // note virtual destructor
    virtual void func(){ cout << "A func" << endl; }
};
class B : public A {
    B(){}
    virtual ~B(){}
    virtual void func(){ cout << "B func" << endl; }
};
class C : public A {
    C(){}
    virtual ~C(){}
    virtual void func(){ cout << "C func" << endl; }
}
now if we have a pointer to base class we can call func() on it and the correct function is called depending on whether the pointer actually points at an A, a B or a C. Example:
A* p1 = new A;
A* p2 = new B;
A* p3 = new C;
p1->func();
p2->func();
p3->func();
will output the following
A func
B func
C func
Now you may say why not use three different pointers to A, B and C types separately but what if you wanted an array of pointers? Then they would all need to be the same type, namely A*. This type of polymorphism is useful for grouping things which are similar in function or spirit but different in implementation.