i would say it depends on what kind of thing your coding, i used "dynamic binding" not so long ago when coding the solution to a topcoder problem. the relevant code is below
Code:
struct node
{
virtual int calc() const =0;
};
struct val_node : public node
{
int val;
val_node() : val(0) {}
int calc() const { return val; }
};
struct binop_node : public node
{
char op;
node *left, *right;
binop_node() : op('p'), left(NULL), right(NULL) {}
int calc() const {
int l=left->calc();
int r=right->calc();
if(op=='d') return l/r; else return l+r;
}
};
my function created a tree of nodes from the input and then called topNode->calc(), without virtual functions it would have been possible but a bit more of a pain to do and would have taken longer. This wasnt a massive application, it was only 100 lines of code but virtual functions were the quickest way to do it.
there are many things where dynamic binding can be very useful perhaps you have just never attempted anything where it would provide a significant improvement in some way. try the following examples without polymorphism
a) create a parsing tree for some simple language
b) drawing a list of drawable objects
c) implementing different types of ai players(in a game) with a common interface
you should find these much easier with virtual functions and base classes.