Yes and no! OO-style dynamic polymorphism, which you get by calling virtual functions, is one of the two major ways C++ offers to achieve polymorphism, and the one you should use for things that can’t be known at compile time. The other is generic-programming-style static polymorphism, which you get by using templates, and you should often use for things that are known at compile time. They’re two great tastes that taste great together.
Without virtual functions, C++ wouldn’t be object-oriented. Operator overloading and non-
virtual member functions are great, but they are, after all, just
syntactic sugar for the more typical C notion of passing a pointer to a
struct to a function. The standard
library contains numerous templates that illustrate “generic programming” techniques, which are also great, but
virtual functions are still at the heart of object-oriented programming using C++.
From a business perspective, there is very little reason to switch from straight C to C++ without
virtual functions (for now we’ll ignore generic programming and the standard library). Technical people
often think that there is a large difference between C and non-OO C++, but without OO, the difference usually isn’t
enough to justify the cost of training developers, new tools, etc. In other words, if I were to advise a manager
regarding whether to switch from C to non-OO C++ (i.e., to switch languages but not paradigms), I’d probably
discourage him or her unless there were compelling tool-oriented reasons. From a business
perspective, OO can help make systems extensible and adaptable, but just the syntax of C++
classes without OO may not even reduce the maintenance cost, and it surely adds to the training cost significantly.
Bottom line: C++ without
virtual is not OO. Programming with classes but without dynamic binding is called “object
based,” but not “object oriented.” Throwing out
virtual functions is the same as throwing out OO. All you have left is
object-based programming, similar to the original Ada language (the updated Ada language, by the way, supports true OO
rather than just object-based programming).
Note: you don’t need
virtual functions for generic programming. Among other things, this means
you can’t tell which paradigm you’ve used simply by counting the number of
virtual functions you have.