It's to induce polymorphic behaviour, which means that a single contract can be used by a client to invoke different behaviours, without the client having to know about every possible behaviour.
A* a = new B();
a->n(); // Will call B::n();
As a more concrete example, here some fairly stereotypical code:
struct Shape {
GLfloat transform_[4][4];
void render() const {
glPushMatrix();
glMultMatrixf(&transform_[0][0]);
draw();
glPopMatrix();
}
virtual void draw() const = 0;
};
struct Line : public Shape {
GLfloat x1, y1, x2, y2;
void draw() {
glBegin();
glVertex2f(x1, y1);
glVertex2f(x2, y2);
glEnd();
}
};
struct Square : public Shape {
GLfloat size;
void draw() {
GLfloat f = size/2;
glBegin();
glVertex2f(-f, -f);
glVertex2f( f, -f);
glVertex2f( f, f);
glVertex2f(-f, f);
glVertex2f(-f, -f);
glEnd();
}
};
void renderShapes(Shape* shapes, int nShapes) {
for (int i = 0; i < nShapes; ++i) {
shapes[i]->render();
}
}
(Disclaimer: The above code is neither correct nor complete, and is certainly not to be held up as an example of good graphics code. It's just to illustrate when virtual functions are useful.