When I first met with virtual functions I've seen explanations that link use of virtual functions to polymorphism, overriding, and late binding (or dynamic binding). Working in software company on my own project, it was not enough for me since these explanations did not show me the practical meaning of virtual functions and special requirements that forced to design virtual functions mechanism. Notably, though virtual functions use overridding mechanism, a developer is not bound to virtual keyword to implement overriding. Sublassing base class, he can just make its own implementation (in derived class) of the function defined in the base class. C++ provides it without any use of virtual functions (see sample). Moreover, to my confusing, some books defined polymorphism "as a property of base class providing interaction with virtual functions that can be defined differently by several derived classes" (Bruneau Babet: Lean & Mean Borland C++, albeit good C++ reference). This is a too broad definition. Too see it, substitute in this definition "polymorphism" with "overrriding" and the definition will make sense! ("overriding" provides that some function defined in the base class "can be defined differently by several derived classes"). Lastly, late binding menanism used by virtual functions sounded to me interesting, but not added much to the understanding of polymorphism in practical terms. Many MFC developers often use overrides of virtual functions defined in their base class in their own classes and they often don't use new (used for late binding) keyword to work with these classes. The sample shows that a key to understanding of virtual functions mechanism is the use of a pointer to the base class. The same (key word) pBase->PrintVirtual() call can invoke different implementations of base class function that can be defined in the derived classes. If no function defined in the derived class, base class implementation will be used. To figure out the practical meaning of this, recall how MFC lets you to override virtual functions defined in the base class with your own. Let's say you deriving your own class from CWnd. CWnd provides a virtual function PreCreateWindow to set properties for a window class. Internally, MFC uses a CWnd pointer to access PreCreateWindow function. When you create your own application you can do nothing with libraries provided by MFC, you just take them as they are, and work with them. However you still need to set your own properties of the window you create and therefore need to override PreCreateWindow function. On the other hand MFC (implemented not by you) must figure out that it should use not its own PreCreateWindow function, but your own PreCreateWindow function defined as a derived class. Technically, CWnd pointer must call your own PreCreateWindow function, and ignore CWnd's own. This is the point where polymorphism, late binding, and overriding are all contribute to the mechanism realized by virtual functions. Late bindind provides that a real implementaion of function to be called will be determined at the run-time, though initially CWnd pointer is only told to call CWnd-defined PreCreateWindow. MFC's library pointer that you import as a third-party software product need not to be modified in order to make a right call in your custom application (is this not a magic!). Polymorphism provides (note that polymorphism will not work without late binding) that the same call pWnd->PreCreateWindow(...) inside MFC can invoke a function provided by late binding mechanism. In this picture, overriding refers to development-level description of mechanisms realized by polymorphism and late binding. It was a design requirement of MFC classes that base class pointers to functions declared virtual should not not know anything about implementations in the one of the derived classes that a developper can realize, but nevertheless a developer should be able to make this pointer to call choosen own derived function even if he import base class from import library developped not by him. At the same time, a developp does not need to see or modify source code (albeit class description still needed).