C++多态(四)---虚函数表详解

C++多态

在C++多态(三)中已经得知,虚函数表地址存放在对象的内存模型中,通过该指针(vfptr),可以访问到该对象的虚函数表。

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

private:
	int _b1 = 1;
	int _b2 = 2;
};

b为Base类的对象,&b为b在内存中的地址。
在这里插入图片描述

一般继承下的虚函数表

一般的继承方式下,基类和派生类中的虚函数可能发生覆盖,也可能存在着自己的虚函数。

一般继承(无虚函数覆盖)

如下是继承下的无函数覆盖的情况下,继承体系中无覆盖的情况。

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

private:
	int _b1 = 1;
	int _b2 = 2;
};

class Derived : public Base
{
public:
	virtual void f1(){ cout << "Derived::f1()" << endl; }
	virtual void g1(){ cout << "Derived::g1()" << endl; }
	virtual void h1(){ cout << "Derived::h1()" << endl; }
};

在这里插入图片描述
可以发现,派生类虚函数表中的基类虚函数放在了虚函数表的前面,紧接着是派生类中的虚函数,并且虚函数表以0(在VS2013下运行)为结束符标志。
在这里插入图片描述

一般继承(有虚函数覆盖)
class Base
{
public:
	virtual void f(){ cout << "Base::f()" << endl; }
	virtual void g(){ cout << "Base::g()" << endl; }
	virtual void h(){ cout << "Base::h()" << endl; }

private:
	int _b1 = 1;
	int _b2 = 2;
};

class Derived : public Base
{
public:
	virtual void f(){ cout << "Derived::f()" << endl; } //存在覆盖的情况
	virtual void g1(){ cout << "Derived::g1()" << endl; }
	virtual void h1(){ cout << "Derived::h1()" << endl; }
};

在这里插入图片描述
可以发现,派生类中f()成员函数覆盖了基类中的f()成员函数,在我们看到的派生类中的虚函数表下,少了一个地址,所以在根据地址指向的函数可以发现,缺少的那个正是派生类虚函数覆盖的基类虚函数
在这里插入图片描述

多继承下的虚函数表

多重继承下无函数覆盖

在这里插入图片描述
派生类中的虚函数放在第一个基类中,其余的虚函数表各自存放之自身虚函数

多重继承下存在函数覆盖
class Base1
{
public:
	virtual void f(){ cout << "Base::f()" << endl; }
	virtual void g(){ cout << "Base::g()" << endl; }
	virtual void h(){ cout << "Base::h()" << endl; }
};

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

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

class Derived : public Base1, public Base2, public Base3
{
public:
	virtual void f(){ cout << "Derived::f()" << endl; } //发生覆盖情况
	virtual void g1(){ cout << "Derived::g1()" << endl; }
	virtual void h1(){ cout << "Derived::h1()" << endl; }
};

在多重继承下,派生类的对象结构,如下所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们可以看到,三个父类虚函数表中的f()函数的位置都替换成了子类中的虚函数。
任意静态类型的父类指针来指向子类,都会调用子类的虚函数

Derive d;
Base1 *b1 = &d;
Base2 *b2 = &d;
Base3 *b3 = &d;
b1->f(); //Derive::f()
b2->f(); //Derive::f()
b3->f(); //Derive::f()
发布了52 篇原创文章 · 获赞 26 · 访问量 3408

猜你喜欢

转载自blog.csdn.net/weixin_43796685/article/details/103717151