0

Just look at the following two class. When I call the functions in "main", what will happen when compiled and program running?

#include <iostream>
#include <string>
using namespace std;
class A{
public:
    virtual void fun2(){cout<<"A::fun2"<<endl;}
};
class B : public A{
public:
    void fun2(){cout<<"B::fun2"<<endl;}
};
int main() {
    A *a = new B();
    B *b = new B();
    //What's the differences among the followings?
    a->A::fun2();
    b->A::fun2();
    A::fun2();

    return 0;
}

I know what the program to print, but I wonder why. I know there is a virtual function table in the object, but when I call

a->A::fun2()

, how it works? Since in the a or b's v-table, the fun2() will print B::fun(), How does the program get into the function A::fun2()?

WangXh
  • 49
  • 5

2 Answers2

1
a->A::fun2();

will print A::fun2


b->A::fun2();

will print A::fun2


A::fun2();

won't be compiled

Humam Helfawi
  • 19,566
  • 15
  • 85
  • 160
  • 2
    For the last one: ```cannot call member function 'virtual void A::fun2()' without object```. – Matthias W. Jan 22 '16 at 08:22
  • I know what the program to print, but I wonder why. I know there is a virtual function table in the object, but when I call 'a->A::fun2()', how it works?Since in the a or b's v-table, the fun2() will print B::fun(), How does the program get into the function A::fun2()? – WangXh Jan 23 '16 at 01:50
  • With both `a->A::fun2()` and `b->A::fun2()` you are telling the compiler to statically call `A::fun2()`, without using virtual function dispatch. Remove the `A::` from both and you will get `B::fun2()` called. – Peter Jan 23 '16 at 11:50
0

From the moment you call a member function through an explicit scoping operator, like

instanceptr->Scope::memberfun()

it is not a virtual function call anymore. The function is just not called via the v-table mechanism anymore.

Class B in your example extends Class A but that doesn't mean that the code for the member function A::fun2() does not exist anymore - it's there, in your object file, and the compiler just calls that function directly.

emvee
  • 4,371
  • 23
  • 23
  • Thank you. The "instanceptr->Scope" is just a scope? how to explain it? how about: > a->A::A::A::fun2()? or > a->B::A::A::fun2()? How to explain the " a->A::A::A:: ..." and "a->B::A::A..."? – WangXh Jan 24 '16 at 04:56
  • And if in class A has another member function: void print() { fun2(); }. If I call a->print() , when program get into member function print(), will the fun2() will be called via v-table? – WangXh Jan 25 '16 at 07:59
  • `a->A::A::A::fun2()` is invalid. Wether or not an object is inherited, you can always force the compiler to call a specific member function. In this example, the "B" object in reality is an A object with some stuff added/overridden. So, in B's namespace there are, in fact, two definitions of "fun2()". One version is the one it inherited from A, the other one is its own version. It is possible to explicitly force the compiler to choose a specific one. The mechanism to do this is via the explicit scoping. – emvee Jan 25 '16 at 11:06