c++ - 派生类声明新的虚函数后再派生,虚函数表里没有新的虚函数地址
迷茫
迷茫 2017-04-17 12:01:48
0
1
416

有这样三个类的声明:

class A {
public:
    virtual void fun1() {
        cout << "A::fun1" << endl;
    }
};

class B : public A {
public:
    virtual void fun1() {
        cout << "B::fun1" << endl;
    }
    virtual void fun2() {
        cout << "B::fun2" << endl;
    }
};

class C : public B {
public:
    virtual void fun2() {
        cout << "C::fun2" << endl;
    }
};

B *pb1 = new B;
B *pb2 = new C;
pb1->fun2(); // B::fun2
pb2->fun2(); // C::fun2

B继承A后,新声明了个虚函数fun2,并被C继承,此时用B的指针指向C的对象可以实现多态。然而观察内存发现B和C的虚函数表里只保存了fun1的地址,并没有fun2的地址:

即使直接观察内存也是没有的:

可以看到C的虚函数表里,第一个地址0x008814e7就是B::fun1的地址,而后一个地址0x008814dd却不是B::fun2或C::fun2的地址


那么,程序在运行时是怎么找到fun2的地址的呢?

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

Antworte allen(1)
大家讲道理

真实的情况是这样的。你的B不仅覆盖了A,还增加了一个虚函数,所以B里面就会有两张虚函数表,一张用来保存fun1,一张用来保存fun2。

因此写成C语言大概就这样:

void A_fun1(A* this)
{
    cout << "A::fun1" << endl;
}

void B_fun1(A* this)
{
    cout << "B::fun1" << endl;
}

void B_fun2(B* this)
{
    cout << "B::fun2" << endl;
}

void C_fun2(B* this)
{
    cout << "C::fun2" << endl;
}

struct vtable_A
{
    void (*fun1)(A*);
};

struct vtable_B
{
    void (*fun2)(B*);
};

vtable_A vtable_A_instance_A = { &A_fun1 };
vtable_A vtable_A_instance_B = { &B_fun1 };
vtable_B vtable_B_instance_B = { &B_fun2 };
vtable_B vtable_B_instance_C = { &C_fun2 };

struct A
{
    vtable_A* vtable;
};

struct B
{
    A _A;
    vtable_B* vtable;
};

struct C
{
    B _B;
};

void ctor_A(A* a)
{
    a->vtable = &vtable_A_instance_A;
}

void ctor_B(B* b)
{
    ctor_A(&b._A);
    b->_A.vtable = &vtable_A_instance_B;
    b->vtable = &vtable_B_instance_B;
}

void ctor_C(C* c)
{
    ctor_B(&c._B);
    c._B.vtable = &vtable_B_instance_C;
}

int main()
{
    B* pb1 = (B*)malloc(sizeof(B));
    ctor_B(pb1);
    C* temp = (C*)malloc(sizeof(C));
    ctor_C(temp);
    B* pb2 = &temp._B;
    pb1->vtable->fun2(pb1);
    pb2->vtable->fun2(pb1);
    return 0;
}
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!