0

So here is code sample. The task was to give output that this code will print out. Is it 2 different functions? What happens with vtable in B class then? Does it just store 2 pointers on 2 different functions with same name?

#include<iostream>
#include <vector>
using namespace std;
class A
{
public:
    A()
    {
        init();
    }
    virtual void init(bool a = true)
    {
        if(a)
            cout << "A" << endl;
    }
};
class B :public A
{
public:
    virtual void init()
    {
        cout << "B" << endl;
    }
};

int main()
{
    B b;
    A* a = &b;
    a->init();
    a->init(true);
    system("pause");
}

Couldn't really find where to read about this case. Could you mates explain or give a link to some source if you've seen this case?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Edwin Paco
  • 121
  • 2
  • 7
  • Try compiling it with warnings enabled - you should get at least one helpful warning which will give you some insight... – Paul R Nov 13 '18 at 16:05
  • @PaulR GCC [remains silent](http://coliru.stacked-crooked.com/a/4ea14d3bb087bfa0). – HolyBlackCat Nov 13 '18 at 16:06
  • 1
    Oh, clang is evidently more helpful then... `:21:18: warning: 'B::init' hides overloaded virtual function [-Woverloaded-virtual] virtual void init() ^ :12:18: note: hidden overloaded virtual function 'A::init' declared here: different number of parameters (1 vs 0) virtual void init(bool a = true)` – Paul R Nov 13 '18 at 16:07
  • 1
    This is the reason for `override`. – molbdnilo Nov 13 '18 at 16:09
  • FWIW MSVC++ also generates a warning. Neither gcc or ICC do though. – Paul R Nov 13 '18 at 16:14
  • 1
    Every function you write is different from others. The real question is «when I make a call, which one is selected?» – Jean-Baptiste Yunès Nov 13 '18 at 16:22
  • Don't use the silly `system("pause");` if you want to keep the window open. Use "Start Without Debugging" (Ctrl+F5) instead. – harper Nov 13 '18 at 16:24
  • 2
    @PaulR gcc will warn if you explicitly add the `-Woverloaded-virtual` switch which you have shown in the clang warning message. – Pates Nov 13 '18 at 20:00

1 Answers1

2

They were already two different functions (overriding doesn't change that), but because they have a different signature, the one in B does not override the one in A.

Remember, the name of a function is only part of its identity! Its parameter list matters too.

If you'd put the override keyword on B::init() then your program would have failed to compile because B::init() doesn't actually override anything (there is no init(), virtual or otherwise, in its base).

Nothing really "happens" with the vtable that wouldn't also have happened if the two functions literally had different names, like A::init(bool) and B::urgleburgleboop().

Note that, quite aside from virtual and polymorphism and overriding, B::init() also "hides" A::init(bool) for normal overload resolution (thanks, C++!), and because of this Clang will warn on your code.

As for where you can read about it, your C++ book would be a good start. :)

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Good answer, I was writing one using `nm` and showing that the mangled symbols are different for the two methods signatures but the theory is enough there. – Tezirg Nov 13 '18 at 16:14