【C++面试】关于虚函数的常见问题
1.虚函数的代价
1)带有虚函数的每个类会产生一个虚函数表,用来存储虚成员函数的指针
2)带有虚函数的每个类都会有一个指向虚函数表的指针
3)不再是内敛函数,因为内敛函数可以在编译阶段进行替代,而虚函数表示等待,在运行阶段才能确定到达采用哪种函数,所以虚函数不是内敛函数
2.那些函数不能是虚函数?
1)构造函数:对象的虚函数表指针需要通过构造函数初始化
2)内联函数:内联函数可以在编译阶段进行函数体的替换,而虚函数需要在运行期间进行确定
3)静态函数:静态函数不属于对象而属于类,因为静态成员函数没有this指针,所以无法访问对象的虚表指针,也就
无法访问类的虚函数表,将静态函数设置成虚函数也就没有任何意义,所以c++语法不支持将静态函数设置成虚函数
4)友元函数:友元函数不属于类,也不能被继承,没有继承特性的函数没有虚函数的说法
5)类外的普通函数:类外普通函数不是类的成员函数,同样不具备继承特性,也就没有虚函数的说法
3.虚函数和纯虚函数的区别?
1)纯虚函数只有定义,没有实现,虚函数既有定义,又有实现
2)含有纯虚函数的类不能定义对象,含有虚函数的类可以定义对象
4.菱形继承的内存结构?如何解决菱形继承存在的问题?
#include <iostream>
using namespace std; class A
{
public:
int x;
virtual int getx()
{
return x;
}
};
class B:public A{};
class C:public A{}; class D:public B,public C{}; int main()
{
D d;
//以下代码不会被任何编译器通过,因为存在菱形继承问题
cout<<d.getx()<<endl;
}
1)菱形继承的内存结构:现在有A,B,C,D四个类,B,C分别继承A类,D通过多重继承继承了BC两个类,现在D类中有两个getx(),D类不知道调用哪一个getx()
2)菱形继承的解决办法:虚继承
BC类都用Virtual标注,保证只有一个getx()被创建
#include <iostream>
using namespace std; class A
{
public:
int x=;
virtual int getx()
{
return x;
}
};
class B:virtual public A{};
class C:virtual public A{}; class D:public B,public C{}; int main()
{
D d;
cout<<d.getx()<<endl;
}
5.虚析构函数的作用?父类的析构函数为什么一定要设置成虚函数?
父类虚析构函数就是为了避免内存泄漏,防止子类内存得不到释放造成内存泄漏
1.当父类的析构函数不声明成虚析构函数时,当子类继承父类,父类指针指向子类对象,delete掉父类指针,只会调动父类的析构函数,而不会调用子类的析构函数,从而造成子类对象内存泄漏
2.当父类的析构函数声明成虚析构函数时,当子类继承父类,父类指针指向子类对象,delete掉父类指针,先调动父类的析构函数,然后调用子类的析构函数,不存在子类对象内存泄漏的问题
只要存在继承关系,则父类的虚函数必须定义成虚函数!
6.构造函数和析构函数中为什么不可以调用虚函数?
背景知识:
1.构造子类对象时,首先调用父类构造函数初始化对象的父类部分,在执行父类的构造函数时,对象的子类部分都是未初始化的,实际上此时对象还不是一个子类对象
2.析构子类对象时,先析构子类部分,然后按照构造顺序逆序析构父类部分
所以在运行子类的构造和析构函数时,对象都是不完整的,为了适应这种不完整,编译器视对象类型为当前构造或析构函数所在类的类型,由此造成的结构就是:在父类的构造或析构函数中,会将子类对象当作父类对象看待
在这样的背景下
如果我们在父类的构造或析构函数中调用虚函数,调用的往往是当前类的虚函数,达不到多态的效果,跟普通函数调用没有区别
7.构造函数为什么不能为虚函数?什么情况下析构函数必须为虚函数?
1)因为虚函数表指针必须在构造函数中初始化,所以构造函数不能为虚函数!
2)当存在继承关系时,父类的析构函数必须为虚函数,这样在父类指针指向子类对象,delete父类指针时,子类对象才不会内存泄漏
【C++面试】关于虚函数的常见问题的更多相关文章
- C++面试常见问题——12虚函数
虚函数 虚函数的工作原理 虚函数的实现要求对象携带额外的信息,这些信息用于确定运行时调用哪一个虚函数,这一信息具有一种被称为虚函数表指针(vptr)的指针形式.vptr指向一个被称为虚函数表(vtbl ...
- 【校招面试 之 C/C++】第11题 C++ 纯虚函数
1.纯虚函数 成员函数的形参后面写上=0,则成员函数为纯虚函数. 纯虚函数声明: virtual 函数类型 函数名 (参数表列) = 0: class Person { virtual void Di ...
- 【校招面试 之 C/C++】第10题 C++不在构造函数和析构函数中调用虚函数
1.不要在构造函数中调用虚函数的原因 在概念上,构造函数的工作是为对象进行初始化.在构造函数完成之前,被构造的对象被认为“未完全生成”.当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数, ...
- 继承虚函数浅谈 c++ 类,继承类,有虚函数的类,虚拟继承的类的内存布局,使用vs2010打印布局结果。
本文笔者在青岛逛街的时候突然想到的...最近就有想写几篇关于继承虚函数的笔记,所以回家到之后就奋笔疾书的写出来发布了 应用sizeof函数求类巨细这个问题在很多面试,口试题中很轻易考,而涉及到类的时候 ...
- 以boost::function和boost:bind取代虚函数
转自:http://blog.csdn.net/Solstice/archive/2008/10/13/3066268.aspx 这是一篇比较情绪化的blog,中心思想是“继承就像一条贼船,上去就下不 ...
- C++ Primer--虚函数与纯虚函数的区别
首先:强调一个概念 定义一个函数为虚函数,不代表函数为不被实现的函数. 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数. 定义一个函数为纯虚函数,才代表函数没有被实现. 定义纯虚函数是为了实 ...
- 你好,C++(37)上车的人请买票!6.3.3 用虚函数实现多态
6.3.3 用虚函数实现多态 在理解了面向对象的继承机制之后,我们知道了在大多数情况下派生类是基类的“一种”,就像“学生”是“人”类中的一种一样.既然“学生”是“人”的一种,那么在使用“人”这个概念 ...
- boost::function和boost:bind取代虚函数
以boost::function和boost:bind取代虚函数 这是一篇比较情绪化的blog,中心思想是"继承就像一条贼船,上去就下不来了",而借助boost::function ...
- C++里面关于虚函数的一些注意点
最后,总结一下关于虚函数的一些常见问题: 1) 虚函数是动态绑定的,也就是说,使用虚函数的指针和引用能够正确找到实际类的对应函数,而不是执行定义类的函数.这是虚函数的基本功能,就不再解释了. 2) 构 ...
随机推荐
- [Codeforces 1242B]0-1 MST
Description 题库链接 给你一张 \(n\) 个点的完全图,其中有 \(m\) 条边长度为 \(1\),其余全为 \(0\).问你这张图的最小生成树为多少. \(1\leq n\leq 10 ...
- 关于原生js的节点兼容性
关于节点的兼容性: 1:获取元素的子节点 a: childNodes:获取元素的子节点,空文本,非空文本,注释,获取的比较全面, 如果只是想获取元素的子节点,请用(children) b: c ...
- 11-Flutter移动电商实战-首页_屏幕适配方案和制作
1.flutter_ScreenUtil插件简介 flutter_ScreenUtil屏幕适配方案,让你的UI在不同尺寸的屏幕上都能显示合理的布局. 插件会让你先设置一个UI稿的尺寸,他会根据这个尺寸 ...
- 20199302《Linux内核原理与分析》第十二周作业
ShellShock攻击实验 什么是ShellShock? Shellshock,又称Bashdoor,是在Unix中广泛使用的Bash shell中的一个安全漏洞,首次于2014年9月24日公开.许 ...
- c++读写matlab中.mat数据
前言:在进行图形图像处理时,经常会用到matlab进行算法的仿真验证,然后再移植到别的语言中.有时会涉及到数据的交互,比如直接读取matlab的.mat类型数据,或者是将c++中的数组存为.mat,为 ...
- jar包更新
打包新的jar包 java -jar xx.jar 本地测试后 删除旧的jar包 然后要重启jar包
- WinDbg常用命令系列---显示当前异常处理程序链!exchain
!exchain 这个!exchain扩展命令显示当前异常处理程序链. !exchain [Options] 参数: Options下列值之一: /c 如果检测到异常,则显示与调试C++ try/c ...
- Git常用命令及常见报错:You have not concluded your merge (MERGE_HEAD exists)、清理无效的远程追踪分支
一.常用命令 切换到master分支:git checkout master 查看已有本地及远程分支:git branch -a(先git pull拉下全部数据) 查看远程分支:git branch ...
- Mac下Pycharm中升级pip失败,通过终端升级pip
使用 Pycharm 使,需要下载相关的第三方包,结果提示安装失败,提示要升级 pip 版本,但是通过 Pycharm 重新安装却失败,原因可能是出在通过 Pycharm 时升级 pip 是没有权限的 ...
- 如果要对img里面的值做特殊处理,可以直接写方法
html <img :src="getMore('up')" alt=""> data里面定义的 one: 'http://p1.fishqc.ne ...