123

Let's assume this scenario in Visual C++ 2010:

#include <iostream>
#include <conio.h>

using namespace std;

class Base
{
public:
    int b;
    void Display()
    {
        cout<<"Base: Non-virtual display."<<endl;
    };
    virtual void vDisplay()
    {
        cout<<"Base: Virtual display."<<endl;
    };
};

class Derived : public Base
{
public:
    int d;
    void Display()
    {
        cout<<"Derived: Non-virtual display."<<endl;
    };
    virtual void vDisplay()
    {
        cout<<"Derived: Virtual display."<<endl;
    };
};

int main()
{
    Base ba;
    Derived de;

    ba.Display();
    ba.vDisplay();
    de.Display();
    de.vDisplay();

    _getch();
    return 0;
};

Theoretically, the output of this little application should be:

  • Base: Non-virtual display.
  • Base: Virtual display.
  • Base: Non-virtual display.
  • Derived: Virtual display.

because the Display method of the Base class is not a virtual method so the Derived class should not be able to override it. Right?

The problem is that when I run the application, it prints this:

  • Base: Non-virtual display.
  • Base: Virtual display.
  • Derived: Non-virtual display.
  • Derived: Virtual display.

So either I didn't understand the concept of virtual methods or something strange happens in Visual C++.

Could someone help me with an explanation?

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
Leif Lazar
  • 1,386
  • 2
  • 11
  • 12
  • you would absolutely have __Base: Non-virtual display.__ when changing your line to `de.Base::Display()`. – v.oddou Mar 28 '14 at 03:45

3 Answers3

178

Yep, you are misunderstanding a little.

The method of the same name on the derived class will hide the parent method in this case. You would imagine that if this weren't the case, trying to create a method with the same name as a base class non-virtual method should throw an error. It is allowed and it's not a problem - and if you call the method directly as you have done it will be called fine.

But, being non-virtual, C++ method lookup mechanisms that allow for polymorphism won't be used. So for example if you created an instance of your derived class but called your 'Display' method via a pointer to the base class, the base's method will be called, whereas for 'vDisplay' the derived method would be called.

For example, try adding these lines:

Base *b = &ba;
b->Display();
b->vDisplay();
b = &de;
b->Display();
b->vDisplay();

...and observe the output as expected:

Base: Non-virtual display.
Base: Virtual display.
Base: Non-virtual display.
Derived: Virtual display.

sje397
  • 41,293
  • 8
  • 87
  • 103
  • Hi @sje397, thank you for your reply. Can you write an example of calling the method, as you said, via a pointer to the base class? Thank you! – Leif Lazar Jun 17 '12 at 00:31
  • also as I said you can ALSO call the (non-virtual) base method from the derived instance, using scope resolution syntax. – v.oddou Mar 28 '14 at 03:47
  • 1
    So, just to be sure, I can define a method in base class, and override it in derived class, irrespective of declaring it as virtual or not. The only difference is that if a base pointer points to a derived class object, then calling that method will cal the base class' method if it is not virtual, and the derived class' method if it is virtual. Is that right? Is there any other difference? – SexyBeast Nov 08 '14 at 21:40
  • @Cupidvogel Yep, that's correct. Declaring it 'virtual' means C++ will use mechanisms to support polymorphism and check to see if there is a more derived version of the method when you call via a base class pointer. I can't think of any other difference. – sje397 Nov 09 '14 at 08:07
  • Is it enough to change the header file only? Or, must the source be compiled with the "virtual" keyword? – Paul Knopf Apr 03 '15 at 06:38
  • @PaulKnopf The 'virtual' keyword is not allowed on a definition outside of the class declaration itself. So no you don't have to add it to the cpp file. You will need to recompile though, of course. – sje397 May 05 '15 at 08:57
  • 1
    Is it ever good practice or is there ever a good reason to override a non virtual method? – Joshua Segal Aug 24 '20 at 14:24
37

Yes you have misunderstood a little:

Pure virtual functions:

virtual void fun1()=0 -> must be overridden in the derived class

Virtual functions:

virtual void fun2() -> can be overridden

Normal functions:

void fun3() -> don't override it

In order to achieve runtime polymorphism you need to override virtual functions in c++

Sub 6 Resources
  • 1,674
  • 15
  • 31
Avinash Aitha
  • 377
  • 3
  • 2
11

I think it might be also better to look at it in the context of static vs dynamic binding.

If the method is non-virtual (it's already by default in C++ unlike Java), then the method binds to it's caller at compile time which is impossible to know the actual object that will be pointed at runtime. So, variable type is all that matters which is the 'Base'.

stdout
  • 2,471
  • 2
  • 31
  • 40