虚拟基础子对象在完整对象中的所有基础子对象之间“共享”。由于 A 在 D::C::B 和 D::B 之间共享,因此无法判断哪个 B 对象应该将其f()
称为覆盖A::f().
考虑:
#include <iostream>
struct A {
virtual void f() = 0;
virtual ~A() {}
};
struct B : virtual A
{
void f() { std::cout << "B\n"; }
};
struct C : virtual A
{
void f() { std::cout << "C\n"; }
};
struct D : C, B {};
int main() {
D d;
A *a = dynamic_cast<A*>(&d); // single shared A between B and C
a->f(); // Should B::f() be called, or C::f()?
}
D 中的 B 和 C 基础子对象都共享相同的 A 基础子对象。当我们调用 A::f() 时,对覆盖函数进行了虚拟查找。但是 B 和 C 都试图覆盖它,那么哪一个“获胜”?x->f()
打印“B”还是“C” ?答案是进入这种情况的程序是不正确的。
当我们通过使 B 和 C 非虚拟继承来消除共享时,单独的 A 基子对象各自的功能都被唯一的基类覆盖:
#include <iostream>
struct A {
virtual void f() = 0;
virtual ~A() {}
};
struct B : A
{
void f() { std::cout << "B\n"; }
};
struct C : A
{
void f() { std::cout << "C\n"; }
};
struct D : C, B {};
int main() {
D d;
// two different A objects
A *a1 = static_cast<A*>(static_cast<B*>(&d));
A *a2 = static_cast<A*>(static_cast<C*>(&d));
a1->f();
a2->f();
}