Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a function of sister class C++

Consider the following code:

#include <iostream>

class A
{
public:
    virtual void f() = 0;
    virtual void g() = 0;
};

class B : virtual public A
{
public:
    virtual void f()
    {
        g();
    }
};

class C : virtual public A
{
public:
    virtual void g()
    {
        std::cout << "C::g" << std::endl;
    }
};

class D : public C, public B
{
};

int main()
{
    B* b = new D;
    b->f();
}

The output of the following program is C::g.

How does the compiler invoke a function of a sister class of class B??

like image 329
Eduard Rostomyan Avatar asked Jun 06 '16 08:06

Eduard Rostomyan


People also ask

What is diamond class in c++?

The Diamond Problem in C++, Solved The Diamond Problem is an ambiguity that arises in multiple inheritance when two parent classes inherit from the same grandparent class, and both parent classes are inherited by a single child class.

What is a virtual inheritance in c++?

Virtual inheritance is a C++ technique that ensures only one copy of a base class's member variables are inherited by grandchild derived classes.

How do you call an inherited class function?

To have a derived function call a base function of the same name, simply do a normal function call, but prefix the function with the scope qualifier (the name of the base class and two colons). The following example redefines Derived::identify() so it first calls Base::identify() and then does its own additional stuff.


1 Answers

N3337 10.3/9

[ Note: The interpretation of the call of a virtual function depends on the type of the object for which it is called (the dynamic type), whereas the interpretation of a call of a non-virtual member function depends only on the type of the pointer or reference denoting that object (the static type) (5.2.2). — end note ]

The dynamic type is type to which pointer really points, not type that was declared as pointed type.

Therefore:

D d;
d.g(); //this results in C::g as expected

is same as:

B* b = new D;
b->g();

And because inside your B::f call to g() is (implicitly) called on this pointer whose dynamic type is D, call resolves to D::f, which is C::f.

If you look closely, it's the (exactly) same behaviour as shown in code above, only that b is now implicit this instead.

That's the whole point of virtual functions.

like image 59
PcAF Avatar answered Oct 08 '22 00:10

PcAF