1

Coming from a Java perspective I was surprised to find that you can only override base methods that have the virtual keyword. In Java you use the final keyword to declare that a method can't be overridden.

I had the idea in my head that you only rarely want to prohibit overriding so that someone can extend your class how they see fit.

So in C++ if you feel that someone might want to at some stage inherit from your class (maybe years later someone thinks its a cool idea) do you make all your methods virtual?

Or is there some critical reason for wanting to prohibit this in C++ that I am unaware of?

for Reference this was the experimenting i did in each language:

Java

    public class Base {

    void doSomething(){
    System.out.println("Doing the base thing");
    }
    }
    public class Derived extends Base {

    void doSomething(){
    System.out.println("Doing the derived thing");
    }

    public static void main(String... argv){
        Base object = new Derived();
        object.doSomething();
    }
    }

C++

    class Base
    {
    public:
        Base(void);
        ~Base(void);
        virtual void doSomething();
    };

    void Base::doSomething(){
        std::cout << "I'm doing the base thing\n" << std::endl;
    }

    class Derived :
        public Base
    {
    public:
        Derived(void);
        ~Derived(void);
        void doSomething();
    };

    void Derived::doSomething(){
        std::cout << "I'm doing the dervied thing" << std::endl;
    }


    int main(void){

        Base * object = new Derived;

        object->doSomething();
        return 0;

    }
bio595
  • 446
  • 2
  • 4
  • 11
  • possible duplicate of [When to mark a function in C++ as a virtual?](http://stackoverflow.com/questions/8298041/when-to-mark-a-function-in-c-as-a-virtual) – Alok Save Jan 03 '12 at 10:35

5 Answers5

1

Yes, in C++ a class method can only be overidden if it is marked virtual in Base class.

If your class is made for inheritance and your class method is meant to provide different behaviors for Base and derived then mark the method as virtual.

Good Read:

When to mark a function in C++ as a virtual?

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
1

Yes, you'd have to make all your methods virtual.

Java took the position that everything was fair game to override by default, and that prohibiting it required action. C++ and C# take the opposite view.

duffymo
  • 305,152
  • 44
  • 369
  • 561
1

duffymo and Als are steering you in the right direction. I just wanted to comment on one thing you said:

So in C++ if you feel that someone might want to at some stage inherit from your class (maybe years later someone thinks its a cool idea) do you make all your methods virtual?

From a software engineering perspective: if you don't have an immediate use for inheritance and aren't using interfaces, then I don't recommend declaring your methods virtual.

Virtual methods come with an ever so slight performance degradation. For non-critical code paths the perf impact is likely negligible. But for class methods that get invoked a lot, it can add up. The compiler can't do as much inlining and direct linkage. Instead, the virtual method to be invoked has to be looked up in the v-table array at runtime.

When someone on my coding team starts off a design conversation with "someone might want at some point later..." that's when my "future proofing" anti-pattern alarm goes off. Designing for extensibility is one thing, but "features for the future" should be put off until then.

And besides - the guy years later who thinks it's a cool idea - Let him be the one to own converting the class methods to be virtual. You'll be onto bigger projects by then anyway. :)

selbie
  • 100,020
  • 15
  • 103
  • 173
  • Note that the performance hit of virtual methods is only true for c++ OR if there are actually different overwritten methods (and even then it can be inlined optimistically, etc.) – Voo Jan 03 '12 at 21:18
0

You can override a method in a base-class even without virtual.

Take this little program for example:

#include <iostream>

struct A
{
    void m()
        { std::cout << "A\n"; }

    virtual void n()
        { std::cout << "A\n"; }
};

struct B : public A
{
    void m()
        { std::cout << "B\n"; }

    virtual void n()
        { std::cout << "B\n"; }
};

int main()
{
    A a;
    a.m();
    a.n();

    B b;
    b.m();
    b.n();

    A &c = b;
    c.m();
    c.n();
}

The output from the program is:

A
A
B
B
A
B

As you can see, the method B::m overrides the same method in A. But that only works when using an exact instance of B. In the third case, when using a reference to the base class you need virtual to make it work.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 4
    `virtual` keyword is necessary for `overidding` or what you get is `Function hiding`. The method `m()` in your derived structure `B` hides the Base structure `A` method, while the method `n()` in `B` overriddes the Base structure method. – Alok Save Jan 03 '12 at 10:41
  • What you did with m() in B is called overloading (which also causes the base class version to be hidden), not overriding. In C++ a function has to be explicitly declared virtual to make it overridable. – Dietmar Kühl Jan 03 '12 at 21:02
0

Programmers coming from languages where virtual functions are the default tend to be surprised that C++ has the reverse choice of defaults, i.e. non-virtual is the default. Note, however, that the contract of a [concrete] virtual function is a lot harder to document and test because there are actually two different contracts involved:

  1. the contract of all overriding functions, i.e. what the function conceptually does
  2. the contract of what the concrete function happens to do

Documenting only one of these won't really cut it because the other half isn't clear at all. This also means that you can't glance from a specific implementation what the actual contract is (assuming you are in the not so untypical situation that the documentation is provided by the source).

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • 1
    For one example of why making everything virtual or inheriting in general may not be such a good idea really often look at all those people who inherited from `HashMap` in Java which didn't turn out as they thought it would. – Voo Jan 03 '12 at 21:19