You are here:

C++/C++ functions

Advertisement


Question
Is function overriding and virtual functions same?
If not, what is the difference?

Answer
This is like asking if eating and food are the same. They are related.

In the same way that food is for eating, so virtual functions are designed to be overridden.

A virtual function allows a class to specify polymorphic behaviour. Sub-classes can change the base class behaviour by overriding the base class virtual function: i.e. by providing their own implementation for it.

We can pass references (or pointers, from now on I'll use the term reference to mean reference or pointer, unless specified otherwise) to any type derived from the base class (i.e. any sub-class of the base class) as a reference to the base class, and calling the virtual function using this reference will cause the specific sub-class behaviour to be performed. The base class behaviour will only be performed if the reference happens to really refer to a base class object instance.

If the function were not specified virtual then re-defining it in a sub-class just hides the base implementation. We do not get the polymorphic behaviour. If we pass a sub-class object as a base class reference to a function and the now non-virtual member function is called using this reference then it will always be the base class implementation that gets called.

Consider the classic example of a shape base class. It has a virtual Draw member function that draws the shape. In this case there is probably no reasonable base class implementation, so this will likely be specified as a pure virtual function: i.e. one for which there is no implementation. As it is pure all specific shape types that can have instances created must override the Draw virtual function i.e. they must define an implementation for it. We pass instances of various types of shape around as references to the shape base class. At some point a shape needs to be rendered, we have no idea what sort of shape we have, we just ask it to draw itself. If it is a square a square is drawn, if it is a circle a circle is drawn etc. In rough outline it would look like so:

   class Shape
   {
   public:
       virtual ~Shape() {}

   // Draw is a pure virtual function. Sub-classes must override
   // to permit instances of them to be created
       virtual void Draw( DrawingContext & ctx ) = 0;

   // ...
   };

   // Square is a Shape, so is publicly derived from it
   class Square : public Shape
   {
   public:
       // Square is a concrete enough kind of Shape to
       // implement a Draw behaviour, so it overrides
       // the non-existent base implementation of Draw
       void Draw( DrawingContext & ctx );

   // ...
   };

   // ...

   void Square::Draw( DrawingContext & ctx )
   {
   // Operations to draw a square
   }

   // Circle is a Shape, so is publicly derived from it
   class Circle : public Shape
   {
   public:
       // Circle is a concrete enough kind of Shape to
       // implement a Draw behaviour, so it overrides
       // the non-existent base implementation of Draw
       void Draw( DrawingContext & ctx );

   // ...
   };

   // ...

   void Circle::Draw( DrawingContext & ctx )
   {
   // Operations to draw a circle
   }

   // ...

   // Some member function of some class Window that
   // take a base Shape reference and calls its Draw
   // operation
   void Window::DrawShape( Shape & shape )
   {
       Shape.Draw(m_ctx);
   }

   // ...

   // In some function somewhere...
   Window wnd( ... );

   // ...

   Circle circle( ... );
   Square square( ... );

   wnd.DrawShape(circle);
   wnd.DrawShape(square);

I have used ellipsis (...) to indicate places where there is missing code either directly or as a comment.

The idea is simple: we have a base Shape class and two sub-classes Circle and Square which override and define the Draw virtual member function. I have assumed you require some parameters to help in drawing a shape, and have called this a DrawingContext (again this may be a base class with specific types such as ScreenDrawContext, MemoryDrawContext and PrinterDrawContext). I give no details of this class.

I have assumed there is some class called Window, which has a member called m_ctx, the drawing context for a Window instance. This class has a member function called DrawShape, which takes a Shape reference and calls its Draw function passing in the window's m_ctx member. I show only the implementation of the Window::DrawShape member function.

Finally I show some code assumed to be in a function somewhere. It defines a Window object called wnd and two shape objects: a Circle and a Square. The constructor parameters for these objects are left unspecified. At some point the circle and square are passed to the wnd DrawShape function to be drawn using the drawing context of the window.  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2012 About.com, a part of The New York Times Company. All rights reserved.