C++复习之路:4.构造函数、析构函数、虚函数等

6.C++虚函数相关(虚函数表,虚函数指针),虚函数的实现原理(热门,重要)虚函数替换过程发生在编译时。虚函数指针是在运行阶段确定的

每个含有虚函数的类都会有至少一个对应的虚函数表。其内存布局为虚函数指针、类内成员变量,其中虚函数指针指向虚函数表(构造过程为:1.拷贝父类虚函数,2.替换子类重写的父类虚函数3.添加子类独有的虚函数

 

1.析构函数一般写成虚函数的原因

执行 Base *base = new Base(); 当 delete base时,会调用析构函数为我们释放资源。而 我们执行Base *son = new Son(); 如果Base基类的析构函数不是虚函数的时候,delete son 对象的时候,只会释放Base基类申请的资源,而不是释放Son派生类的资源。原因如下:(总结:将可能会被继承的父类的析构函数设置为虚函数,可以保证当我们new一个子类,然后使用基类指针指向该子类对象,释放基类指针时可以释放掉子类的空间,防止内存泄漏。)

基类指针指向了派生类对象,而基类中的析构函数是非virtual的,而虚构函数是动态绑定的基础。现在析构函数不是virtual的,因此不会发生动态绑定,而是静态绑定,指针的静态类型为基类指针,因此在delete的时候只会调用基类的析构函数,而不会调用派生类的析构函数。这样,在派生类中申请的资源就不会得到释放,就会造成内存泄漏,这是相当危险的:如果系统中有大量的派生类对象被这样创建和销毁,就会有内存不断的泄漏,久而久之,系统就会因为缺少内存而崩溃。

2.那么为什么系统默认的析构函数不是虚函数

因为虚函数需要额外的虚函数表,虚函数指针,占用了额外的内存。只有当需要作为父类的时候才会去考虑构造函数写成虚函数

3.构造函数为什么一般不定义为虚函数

存储空间角度:虚函数对应一个vtable,vtable存储于对象的内存空间,若构造函数是虚的,则需要通过 vtable来调用,若对象还未实例化,即内存空间还没有,无法找到vtable,陷入死循环,出错。

使用角度:虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用。

构造函数本身就是要初始化实例,那使用虚函数就没有实际意义

从实际含义上看,在调用构造函数时还不能确定对象的真实类型(因为子类会调父类的构造函数);而且构造函数的作用是提供初始化,在对象生命期只执行一次,不是对象的动态行为,也没有太大的必要成为虚函数

4. 构造函数或者析构函数中调用虚函数会怎样

  • 在进入基类构造函数时,调用了基类版本的虚函数
  • 在进入基类析构函数时,调用了基类版本的虚函数

,vptr先指向父类的虚函数表,在父类构造完成之后,子类的vptr才指向自己的虚函数表。也就是说,在父类或者子类的构造函数中调用虚成员函数是没有多态性的。

5. 纯虚函数的作用

纯虚函数可以提供抽象类的功能,抽象类则通常提供统一接口的功能,强迫继承它的派生类各自实现符合自己特点的具体功能,并且一定要有这样的功能,这对于设计和架构非常有用

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

溯夜流云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值