15

Because of C++ nature of static-binding for methods, this affects the polymorphic calls.

From Wikipedia:

Although the overhead involved in this dispatch mechanism is low, it may still be significant for some application areas that the language was designed to target. For this reason, Bjarne Stroustrup, the designer of C++, elected to make dynamic dispatch optional and non-default. Only functions declared with the virtual keyword will be dispatched based on the runtime type of the object; other functions will be dispatched based on the object's static type.

So the code:

Polygon* p = new Triangle;
p->area();

provided that area() is a non-virtual function in Parent class that is overridden in the Child class, the code above will call the Parent's class method which might not be expected by the developer. (thanks to the static-binding I've introduced)

So, If I want to write a class to be used by others (e.g library), should I make all my functions to be virtual for the such previous code to run as expected?

John Dibling
  • 99,718
  • 31
  • 186
  • 324
Muhammad Hewedy
  • 29,102
  • 44
  • 127
  • 219
  • 5
    `p.area()` does not even compile. Maybe you mean `p->area()`? Time to pick up a good book on C++, I'd say. – Kerrek SB Nov 28 '11 at 15:25
  • 2
    It depends upon other design choices you've made. As a developer, I shouldn't care if `p->area()` invokes `Polygon::area()`, `Triangle::area`, or some other function, as long as it returns the correct answer. That is entirely the library's responsibility, and opaque to the library user. – Robᵩ Nov 28 '11 at 15:27
  • You might find [this article](http://www.gotw.ca/publications/mill18.htm) very enlightening. – Björn Pollex Nov 28 '11 at 15:33

5 Answers5

28

The simple answer is if you intend functions of your class to be overridden for runtime polymorphism you should mark them as virtual, and not if you don't intend so.

Don't mark your functions virtual just because you feel it imparts additional flexibility, rather think of your design and purpose of exposing an interface. For ex: If your class is not designed to be inherited then making your member functions virtual will be misleading. A good example of this is Standard Library containers,which are not meant to be inherited and hence they do not have virtual destructors.

There are n no of reasons why not to mark all your member functions virtual, to quote some performance penalties, non-POD class type and so on, but if you really intent that your class is intended for run time overidding then that is the purpose of it and its about and over the so-called deficiencies.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 4
    I was writing a huge answer, but I think this sums it up. – John Dibling Nov 28 '11 at 15:55
  • This means that `final` classes only shouldn't contain virtual methods? as the rest of classes might be inherited by other ppl using my class – Muhammad Hewedy Nov 28 '11 at 16:59
  • @Muhammad: I am not sure what you refer to as `final` classes, there is no such concept in C++ & I am not well versed in Java. – Alok Save Nov 28 '11 at 17:01
  • in Java `final` class (`steal` in C#) is the class that shouldn't be subclassed (such as **1-** Functional classes or classes that better represented by functions - as if math.h methods are being put in some class, **2-** Classes that shouldn't be subclassed for security reasons eg. java.lang.String class) – Muhammad Hewedy Nov 28 '11 at 17:32
  • @Muhammad It has nothing to do with `final`. It is a question of class design. Unless your code is designed explicitly so that the implementation of that function can vary (within specified limits) without violating any of the class invariants, then the function should **not** be virtual---in well written Java (something exceedingly rare), most functions should be declared `final`. It's a design issue, and until you've settled it, it's too early to be writing code. – James Kanze Nov 29 '11 at 10:44
  • @JamesKanze, Plz, can you provide me with more info about this point : `in well written Java (something exceedingly rare), most functions should be declared final. It's a design issue, and until you've settled it, it's too early to be writing code.`? – Muhammad Hewedy Nov 29 '11 at 13:10
  • @Muhammad Since most functions should not be virtual, and in Java, functions are virtual by default, it follows that most should be `final`, to turn off the virtuality. – James Kanze Nov 29 '11 at 18:39
3

Mark it virtual if derived classes should be able to override that method. It's as simple as that.

Pubby
  • 51,882
  • 13
  • 139
  • 180
2

In terms of memory performance, you get a virtual pointer table if anything is virtual, so one way to look at it is "please one, please all". Otherwise, as the others say, mark them as virtual if you want them to be overridable such that calling that method on a base class means that the specialized versions are run.

Sean Duggan
  • 1,105
  • 2
  • 18
  • 48
2

As a general rule, you should only mark a function virtual if the class is explicitly designed to be used as a base class, and that function is designed to be overridden. In practice, most virtual functions will be pure virtual in the base class. And except in cases of call inversion, where you explicitly don't provide a contract for the overriding function, virtual functions should be private (or at the most protected), and wrapped with non-virtual functions enforcing the contract.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • Another positive benefit of keeping public functions non-virtual is that it provides a single breakpoint location before dispatch. – Kevin Hopps Nov 28 '11 at 21:12
0

That's basically the idea ; actually if you are using a parent class, I don't think you'll need to override every methods so just make them virtual if you think you'll use it this way.

Jérémy Dutheil
  • 6,099
  • 7
  • 37
  • 52