When a class inherits from multiple base classes that have virtual functions, the virtual function calls are resolved based on the order of inheritance and the specific class hierarchy.
In C++, when a class inherits from multiple base classes, it can potentially inherit multiple implementations of the same virtual function. To resolve this ambiguity, the compiler uses a mechanism called "virtual function table" (vtable) for each class.
Each class that contains virtual functions has its own vtable, which is an array of function pointers. The vtable contains entries for all the virtual functions declared in the class and its base classes. When a class inherits from multiple base classes, its vtable is constructed by concatenating the vtables of its base classes.
Here's an example to illustrate how virtual function calls are resolved in multiple inheritance:
#include <iostream>
class BaseA {
public:
virtual void foo() {
std::cout << "BaseA::foo()\n"; }
};
class BaseB {
public:
virtual void foo() {
std::cout << "BaseB::foo()\n"; }
virtual void bar() {
std::cout << "BaseB::bar()\n"; }
};
class Derived : public BaseA, public BaseB {
public:
void foo() override {
std::cout << "Derived::foo()\n"; }
};
int main() {
Derived derived;
BaseA* baseA = &derived;
BaseB* baseB = &derived;
baseA->foo();
baseB->foo();
baseB->bar();
}
Derived::foo()
Derived::foo()
BaseB::bar()
In this example, the Derived
class inherits from both BaseA
and BaseB
. Both base classes have their own virtual function foo()
, and BaseB
also has a virtual function bar()
.
When baseA->foo()
is called, the compiler looks up the vtable of BaseA
and finds the entry for foo()
. Since Derived
overrides foo()
, the Derived::foo()
implementation is called.
Similarly, when baseB->foo()
is called, the compiler looks up the vtable of BaseB
and finds the entry for foo()
. Again, since Derived
overrides foo()
, the Derived::foo()
implementation is called.
When baseB->bar()
is called, the compiler looks up the vtable of BaseB
and finds the entry for bar()
. Since Derived
doesn't override bar()
, the BaseB::bar()
implementation is called.
It's important to note that if a derived class inherits from multiple base classes and does not override a virtual function that is present in multiple base classes, the compiler will generate an ambiguity error. To resolve this, you need to explicitly specify which base class's implementation should be used using scope resolution.
class Derived : public BaseA, public BaseB {
public:
void foo() override {
// Explicitly call BaseA's implementation
BaseA::foo();
}
};
In summary, when a class inherits from multiple base classes with virtual functions, the virtual function calls are resolved based on the vtable and the specific class hierarchy. The derived class can override the virtual functions, and the most derived implementation will be called.
Answers to questions are automatically generated and may not have been reviewed.
Learn how to write flexible and extensible C++ code using polymorphism, virtual functions, and dynamic casting