C++之虚函数是如何实现的
来源:互联网 发布:算法模型电商 编辑:程序博客网 时间:2024/05/17 03:29
最近面试过程中问到了虚函数的实现,当时答对了一部分,现在做一个详细的分析:
1.什么是虚函数
在某基类中声明为 virtual 并在一个或多个派生类中被重新定 义的成员函数,用法格式为:virtual 函数返回类型 函数名(参数表) {函数体};,实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数
2.实现多肽的条件
简单的说就是:基类的指针或引用指向子类对象,当子类中成员函数和基类成员函数:函数名相同,参数列表相同,返回值相同,并且基类该函数为虚函数时,基类指针调用该函数时是调用的子类的该函数。
3.虚函数表
对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其容真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,这张虚函数表就显得由为重要了,它就像一个地图一样,指明了实际所应该调用的函数。
这里我们着重看一下这张虚函数表。C++的编译器应该是保证虚函数表的指针存在于对象实例中最前面的位置(这是为了保证取到虚函数表的有最高的性能——如果有多层继承或是多重继承的情况下)。 这意味着我们通过对象实例的地址得到这张虚函数表,然后就可以遍历其中函数指针,并调用相应的函数。
覆盖父类的虚函数是很显然的事情,不然,虚函数就变得毫无意义。下面,我们来看一下,如果子类中有虚函数重载了父类的虚函数,会是一个什么样子?假设,我们有下面这样的一个继承关系。
class Base
{
public:
virtual void f(){}
virual void g(){}
virtual void h(){}
}
class Derive : public Base
{
public:
virtual void f(){}
virtual void g1(){}
virtual void h1(){}
}
为了让大家看到被继承过后的效果,在这个类的设计中,我只覆盖了父类的一个函数:f()。那么,对于派生类的实例,其虚函数表会是下面的一个样子:
Derive::f
Base::g
Base::h
Derive::g1
Derive::h1
我们从表中可以看到下面几点,
1)覆盖的f()函数被放到了虚表中原来父类虚函数的位置。
2)没有被覆盖的函数依旧。
这样,我们就可以看到对于下面这样的程序,
Base *b = new Derive();
b->f();
由b所指的内存中的虚函数表的f()的位置已经被Derive::f()函数地址所取代,于是在实际调用发生时,是Derive::f()被调用了。这就实现了多态。
- C++之虚函数是如何实现的
- C语言中的可变参数函数是如何实现的?
- C++是如何利用虚函数实现多态性的?
- C++是如何利用虚函数实现多态性的?
- C++是如何利用虚函数实现多态性的?
- C++是如何利用虚函数实现多态性的?
- C++是如何利用虚函数实现多态性的?
- 虚函数在C++中是如何实现的
- C++是如何利用虚函数实现多态性的?
- c++面试题2:虚函数是如何实现的?
- C语言是实现函数的重载
- 函数调用是如何在系统中实现的-以C为例
- C++中虚函数是如何实现,多重继承中虚函数的实现
- 如何实现 C 的函数重载
- 转:Object-C 消息函数是如何工作的?
- 【c++】实验说明“转换构造函数”是如何转换的
- wince串口打印函数是如何实现的?
- printf函数可变参数是如何实现的?
- 无法解析的外部符号 关于链接库
- qt绘图的方法
- 记录感想
- J-Link在线调试stm32开发板,无需多次下载,实现仿真
- jdk 中的算法
- C++之虚函数是如何实现的
- ipython:.ipynb文件转其他格式(markdown,HTML,talex等)
- C#代码屏蔽CTRL+ALT+DEL
- 思维导图学Java之Class对象
- 2017onsite比赛游记帖
- [PAT-乙级]1036.跟奥巴马一起编程
- 对于“javac不是内部或外部命令也不是可运行的程序”的解决方法
- httpd正向代理与反向代理技术
- Kali 安装 Nessus 详细过程