#include <iostream>
using namespace std;
class base
{
public:
virtual void f() { cout << "in base::f()\n"; };
virtual void g() { cout << "in base::g()\n"; };
virtual ~base() { cout << "base::~base()\n";};
};
class derived1 : public virtual base
{
public:
derived1() { cout<<"dervied1 constructed\n"; };
void f() { cout << "in derived1::f()\n" ; };
~derived1(){ cout << "derived1::~derived1()\n";};
};
class derived2 : public virtual base
{
public:
derived2(base* b, derived1* d1)
{
cout<<"derived2 constructed\n";
b->f();
d1->g();
};
void g()
{
cout << "in dervied2::g()\n";
};
~derived2()
{
cout << "derived2::~derived2()\n";};
};
class C : public derived1, public derived2
{
public:
C() : derived2 (this, this) {};
void f()
{
cout << "in C::f()\n";
};
~C()
{
cout << "C::~C()\n";
};
};
int main()
{
derived1 d1;
derived2 d2(&d1, &d1 ); // TAG 1
base* c_as_b = new C; // TAG 2
derived2* d2_as_c = new C; // same as TAG 2
c_as_b->f(); // TAG 3
d2_as_c->f(); // TAG 4
delete d2_as_c;
delete c_as_b;
return 0;
}
dervied1 constructed <- result of: derived1 d1;
derived2 constructed -|
in derived1::f() | result of: derived2(&d1,&d1); // TAG 1
in base::g() _|
dervied1 constructed -
derived2 constructed |
in base::f() | result of: base* b_as_c = new C; // TAG 2
in dervied2::g() _|
dervied1 constructed -
derived2 constructed |
in base::f() | same as the above.
in dervied2::g() _|
in C::f()
in C::f()
C::~C()
derived2::~derived2()
derived1::~derived1()
base::~base()
C::~C()
derived2::~derived2()
derived1::~derived1()
base::~base()
derived2::~derived2()
base::~base()
derived1::~derived1()
base::~base()
TAG 1: 具有正确的输出,遵循通过指向基类的指针访问派生类的规则。
标签2: 根据我的理解,在C类构造中,首先构造derived1和derived2,这意味着类C包含一个指向vtable的指针,其中derived1 :: f()覆盖base :: f(),而derived2 :: g()覆盖了base :: g(),所以在构建C类的这个时刻,C :: f()指向derived1 :: f()和C :: g()指向derived2 :: g()... ..但看起来只有一个指向最后一个类构造的vtable的指针,它是derived2,其中derived2 :: g()重写了base :: g(),并且没有覆盖base :: f() 。 [尝试颠倒C类的两个基类的顺序]
对我来说这是一个模糊的角落案例,但看起来所有编制者都同意结果!
有谁能解释这里发生了什么?