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父类指针时,子类对象才不会内存泄漏

最新文章

  1. 交易系统使用storm,在消息高可靠情况下,如何避免消息重复
  2. ssh(sturts2_spring_hibernate) 框架搭建之struts2
  3. 实验9:Problem G: 克隆人来了!
  4. java从一个目录拷贝文件到另一个目录下
  5. .NET C# 使用S22.Imap.dll接收邮件 并且指定收取的文件夹的未读邮件,并且更改未读准态
  6. 关于JQUERY操作XML问题!
  7. 常见的Unix指令
  8. 【开源项目9】ImageLoaderConfiguration详解
  9. 关于Android与pc通信时中文乱码的分析和解决
  10. Matrix multiplication hdu4920
  11. AX2012服务器配置--Windows Server 2012 如何实现多个用户远程桌面登陆?
  12. 如何把apache和nginx 加入到系统服务,用service 命令来控制启动、停止
  13. Linux 安装Redis全过程日志
  14. 一个巨low的“2048”
  15. SQL Server中是否可以准确获取最后一次索引重建的时间?
  16. jmert中如何测试上传文件接口(测试上传excel文件)
  17. Perl的do语句块结构
  18. [AH2017/HNOI2017]影魔
  19. [HBase Manual]CH5 HBase运行模式:单实例和分布式
  20. 时间轴QTimeLine

热门文章

  1. 委托、Lamda表达式
  2. Bootstrap内辅助类,响应式工具,组件的个人总结
  3. [Flutter] Style a message chat style-ish bubble
  4. bfs与dfs小结
  5. C/C++中double类型的比较
  6. POJ P1985 Cow Marathon 题解
  7. Mysql 多表连接查询 inner join 和 outer join 的使用
  8. CF1172E Nauuo and ODT
  9. (8)Go Map
  10. Linux基础及常用指令