c++

了解C多态与虚函数表

发布时间:2022/5/16 20:40:56   点击数:
好的白癜风专家 http://m.39.net/news/ylzx/bjzkhbzy/

什么是多态,多态有什么用途?

定义:“一个接口,多种方法”,程序在运行时才决定调用的函数。

实现:C++多态性主要是通过虚函数实现的,虚函数允许子类重写override(注意和overload的区别,overload是重载,是允许同名函数的表现,这些函数参数列表/类型不同)。

目的:接口重用。封装可以使得代码模块化,继承可以扩展已存在的代码,他们的目的都是为了代码重用。而多态的目的则是为了接口重用。

用法:声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。

关于重载、重写的区别

Overload(重载):在C++程序中,可以将语义、功能相似的几个函数用同一个名字表示,但参数或返回值不同(包括类型、顺序不同),即函数重载。

(1)相同的范围(在同一个类中);(2)函数名字相同;(3)参数不同;

(4)virtual关键字可有可无。

Override(重写):是指派生类函数覆盖基类函数,特征是:

(1)不同的范围(分别位于派生类与基类);(2)函数名字相同;(3)参数相同;

(4)基类函数必须有virtual关键字。

注:重写基类虚函数的时候,会自动转换这个函数为virtual函数,不管有没有加virtual,因此重写的时候不加virtual也是可以的,不过为了易读性,还是加上比较好。

虚函数表

多态是由虚函数实现的,而虚函数主要是通过虚函数表(V-Table)来实现的。

如果一个类中包含虚函数(virtual修饰的函数),那么这个类就会包含一张虚函数表,虚函数表存储的每一项是一个虚函数的地址。如下图:

这个类的每一个对象都会包含一个虚指针(虚指针存在于对象实例地址的最前面,保证虚函数表有最高的性能),这个虚指针指向虚函数表。

注:对象不包含虚函数表,只有虚指针,类才包含虚函数表,派生类会生成一个兼容基类的虚函数表。

原始基类的虚函数表

下图是原始基类的对象,可以看到虚指针在地址的最前面,指向基类的虚函数表(假设基类定义了3个虚函数)

单继承时的虚函数(无重写基类虚函数)

假设现在派生类继承基类,并且重新定义了3个虚函数,派生类会自己产生一个兼容基类虚函数表的属于自己的虚函数表。

Deriveclass继承了Baseclass中的三个虚函数,准确的说,是该函数实体的地址被拷贝到Derive类的虚函数表,派生类新增的虚函数置于虚函数表的后面,并按声明顺序存放。

单继承时的虚函数(重写基类虚函数)

现在派生类重写基类的x函数,可以看到这个派生类构建自己的虚函数表的时候,修改了base::x()这一项,指向了自己的虚函数。

多重继承时的虚函数(Derived::publicBase1,publicBase2)

这个派生类多重继承了两个基类base1,base2,因此它有两个虚函数表。

  

它的对象会有多个虚指针(据说和编译器相关),指向不同的虚函数表。

来源:

转载请注明:http://www.xienasc.com/jbtjt/24275.html

------分隔线----------------------------