Behavior of virtual function in C++
Asked Answered
U

7

10

I have a question, here are two classes below:

  class Base{
      public:
          virtual void toString();       // generic implementation
  }

  class Derive : public Base{
      public:
          ( virtual ) void toString();   // specific implementation
  }

The question is:

  • If I wanna subclass of class Derive perform polymophism using a pointer of type Base, is keyword virtual in the bracket necessary?

  • If the answer is no, what's the difference between member function toString of class Derive with and without virtual?

Underexpose answered 19/4, 2010 at 17:58 Comment(1)
It is optional but some consider it a matter of good style to be explicit about overriding member functions.Comparator
O
13

C++03 §10.3/2:

If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name and same parameter list as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.

Oregon answered 19/4, 2010 at 19:33 Comment(0)
C
10

That keyword there is strictly optional and makes no difference at all.

Cyclist answered 19/4, 2010 at 18:0 Comment(1)
It makes no difference to the compiler. To the human reader it may in fact improve readability. I always explicitly state virtual at all levels of inheritance.Ornamentation
G
7

The virtual property is inherited from the base class and is assumed to be present even if you don't type it out.

Gamal answered 19/4, 2010 at 18:2 Comment(0)
S
1

The compiler already knows from the 'virtual' keyword in the base class that toString is a virtual method. No need to repeat it.

Sachasachem answered 19/4, 2010 at 18:3 Comment(1)
One might add that it might make a difference for the human reader.Pecten
S
1

A function once a virtual always a virtual.

So in any event if the virtual keyword is not used in the subsequent classes, it does not prevent the function/method from being 'virtual' i.e. be overridden. So the following guideline might help from a team development point-of-view :-

  • If the function/method is supposed to be overridden, always use the 'virtual' keyword. This is especially true when used in interface / base classes.
  • If the derived class is supposed to be sub-classed further explicity state the 'virtual' keyword for every function/method that can be overridden.
  • If the function/method in the derived class is not supposed to be sub-classed again, then the keyword 'virtual' is to be commented indicating that the function/method was overridden but there are no further classes that override it again. This ofcourse does not prevent someone from overriding in the derived class unless the class is made final (non-derivable), but it indicates that the method is not supposed to be overridden. Ex: /*virtual*/ void someFunc();
Student answered 19/4, 2010 at 18:13 Comment(5)
For the case of "to be overridden always", one might want to add the pure specifier as well.Unto
I think there's meant to be a comma between "overridden" and "always". i.e. "always use the virtual keyword" and not "always overridden".Dues
@Myke: Except that pure isn't a C++ keyword.Pecten
The "pure specifier" is of the form = 0, not a keyword.Unto
@Myke: Well, well. Who would have thought... I didn't, anyway. :)Pecten
E
0

It doesn't matter to the compiler whether or not you supply the virtual keyword on derived versions of the function.

However, it's a good idea to supply it anyway, so that anyone looking at your code will be able to tell it's a virtual function.

Eroto answered 19/4, 2010 at 20:46 Comment(0)
K
0

It's a matter of good style, and the user-programmer knows what's going on. In C++0x you can use [[override]] to make it more explicit and visible. You can use [[base_check]] to force the usage of [[override]].

If you don't want or can't do that, simply use the virtual keyword.

If you derive without virtual toString, and you cast an instance of Derive back to Base, calling toString() would actually call Base's toString(), since as far as it know's that's an instance of Base.

Kellogg answered 20/4, 2010 at 0:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.