【C++ 继承 | 虚函数表 02】C++虚函数表剖析 ②

索引

 

 

多重继承(无虚函数覆盖)

下面,再让我们来看看多重继承中的情况,假设有下面这样一个类的继承关系。注意:子类并没有覆盖父类的函数。

class Base1
{
public:
    virtual void f() { cout << "Base1::f" << endl; }  //虚函数定义
    virtual void g() { cout << "Base1::g" << endl; }
    virtual void h() { cout << "Base1::h" << endl; }
};

class Base2
{
public:
    virtual void f() { cout << "Base2::f" << endl; }  //虚函数定义
    virtual void g() { cout << "Base2::g" << endl; }
    virtual void h() { cout << "Base2::h" << endl; }
};

class Base3
{
public:
    virtual void f() { cout << "Base3::f" << endl; }
    virtual void g() { cout << "Base3::g" << endl; }
    virtual void h() { cout << "Base3::h" << endl; }
};

class Derive :public Base1, public Base2, public Base3 //多继承的情况——无虚继承覆盖
{
public:
    virtual void f1() { cout << "Derive::f1" << endl; } //虚函数定义
    virtual void g1() { cout << "Derive::g1" << endl; }
};

图解:

对于子类实例中的虚函数表,是下面这个样子:

我们可以看到:
1) 每个父类都有自己的虚表。
2) 子类的成员函数被放到了第一个父类的表中。(所谓的第一个父类是按照声明顺序来判断的)

这样做就是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数。

 

多重继承(有虚函数覆盖)

下面我们再来看看,如果发生虚函数覆盖的情况。

其中:D自身的虚函数与B基类共用了同一个虚函数表,因此也称B为D的主基类(primary base class)。

虚函数替换过程与前面描述类似,只是多了一个虚函数表,多了一次拷贝和替换的过程。

虚函数的调用过程,与前面描述基本类似,区别在于基类指针指向的位置可能不是派生类对象的起始位置,以如下面的程序为例:

参开资料

1. 2.5 虚函数的实现及基本原理

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章