1.多态的机制与虚函数的机制

1.1 多态的机制

1.当在类中使用virtual声明一个函数为虚函数时,在编译时,编译器会自动在基类中默默地安插一个虚函数表指针,同时的.rodata段为这类生成一张虚函数表,用来保存类中的虚函数的地址。

2.当继承发生时,父类中的虚指针就被子类给继承了下来,所以他的类对象空间就增大了一个指针的大小。

3.当子类构造对象时,这根继承而来的虚指针,将会在子类的构造函数中被重新赋值,所赋的值即为子类类中产生的虚函数表地址。

4.当使用父类指针或引用,对虚函数进行调用时,通过这个虚函数表指针,在虚函数表中查找虚函数的地址,从而调用不同类的虚函数。

1.2 虚函数的机制

虚函数的意义何在?就是用来承接动态多态的。他是如何承接这种动态多态机制的呢?

当子类之中函数与父类之中的虚函数重名时,且返回值与形参列表都一致时,将是对父类虚函数的重写。当在子类重写虚函数时,将会把虚函数表中的父类的虚函数地址覆盖掉。

注释:虚函数的具体可以去看主页文章,单继承与多进程

1.3虚函数表的结构图

1.4 动态多态实现的三个前提件(很重要)

1.有继承关系
2.基类中有虚函数,且子类重写虚函数
3.基类指针或引用,指向或引用父类对象,就会形成动态多态

2.多态实例应用

#include <iostream>using namespace std;
class Driver{
public:virtual void show_info(){cout<<"我是司机"<<endl;}
};class Bwm:public Driver
{
public:void show_info(){cout<<"我开的是宝马"<<endl;}
};class Benchi:public Driver
{
public:void show_info(){cout<<"我开的是奔驰"<<endl;}
};class Tuolaji:public Driver
{
public:void show_info(){cout<<"我开的是拖拉机"<<endl;}
};class Kai
{
public:void kaiche(Driver& p){p.show_info();}};int main()
{Bwm bwm;Tuolaji tuolaji;Benchi benchi;Kai p;p.kaiche(tuolaji);p.kaiche(benchi);p.kaiche(benchi);return 0;
}

结果图:

3.多态的巨大问题与虚析构

3.1代码举例说明

#include <iostream>using namespace std;class A
{
public:A(){cout<<"A的构造"<<endl;}~A(){cout<<"A的析构"<<endl;}virtual void show_info(){cout<<"爱吃饭"<<endl;}
};class B:public A
{
public:B(){cout<<"B的构造"<<endl;}~B(){cout<<"B的析构"<<endl;}void show_info(){cout<<"爱吃糖"<<endl;}
};int main()
{A* a=new B;a->show_info();delete a;return 0;
}

结果图:

由图可知:当用虚函数实现多态的时候,子类的的析构无法进行。

所以我们应该怎么解决呢?

3.2代码实现

#include <iostream>using namespace std;class A
{
public:A(){cout<<"A的构造"<<endl;}virtual~A(){cout<<"A的析构"<<endl;}virtual void show_info(){cout<<"爱吃饭"<<endl;}
};class B:public A
{
public:B(){cout<<"B的构造"<<endl;}~B(){cout<<"B的析构"<<endl;}void show_info(){cout<<"爱吃糖"<<endl;}
};int main()
{A* a=new B;a->show_info();delete a;return 0;
}

结果图:

所以,为了避免子类的析构无法执行而造成的内存泄漏问题,应该把最远端父类的析构函数定义为虚析构。虚析构的语法即是在最远端父类的析构函数名前 加virtual进行修饰即可。

虚析构如下:

virtual~A(){//虚析构的定义形式。}

4.纯虚函数与抽象类

4.1纯虚函数语法格式:

class + 类名
{public:virtual void showInfo() = 0;
};

4.2纯虚函数的定义

在类中定义一个没有函数体的虚函数就叫做纯虚函数。类中有纯虚函数的类就叫做抽象类。抽象类被人称接口类。这个纯虚函数只有一个函数名做为函数功能的表现,而没有函数体的实现。纯虚函数必须在子类之中进行实现,如果继承的子类没有实现父类的纯虚函数,那么这个子类也将成员抽象类。抽象类是不可以定义对象的。纯虚函数也叫接口类中的接口。

4.3抽象类的应用实例

#include <iostream>using namespace std;
class A
{
public:virtual void show_info()=0;virtual void goshopping()=0;
};class B:public A
{
public:void show_info(){cout<<"我是大哥"<<endl;}void goshopping(){cout<<"我是小弟"<<endl;}
};int main()
{A* a=new B;a->show_info();a->goshopping();return 0;
}

C++:多态与虚函数,纯虚函数相关推荐

  1. 什么是纯虚函数 纯虚函数的作用 如何定义使用纯虚函数

    什么是纯虚函数 纯虚函数的作用 如何定义使用纯虚函数   一 定义: 纯虚函数是一种特殊的虚函数,它的一般格式如下:  class <类名>  {  virtual <类型>& ...

  2. C++: 虚函数 / 纯虚函数

    虚函数 ● 虚函数是指在基类内部声明的成员函数前添加关键字 virtual 指明的函数 ● 虚函数存在的意义是为了实现多态,让派生类能够重写(override)其基类的成员函数 ● 派生类重写基类的虚 ...

  3. 面试中常被问到(11)虚函数/纯虚函数

    虚函数 如何定义一个虚函数?在基类成员函数前加入virtual关键字,但并不代表此函数不被实现,只是说明允许基类指针调用派生类重写的此函数 一个类只要声明有虚函数或者从基类继承了虚函数,在编译过程中就 ...

  4. 【C++ 语言】面向对象 ( 继承 | 重写 | 子类调用父类方法 | 静态多态 | 动态多态 | 虚函数 | 纯虚函数 )

    文章目录 类的继承 方法的重写 子类中调用父类方法 多态 虚函数 虚函数示例 纯虚函数 相关代码 类的继承 1. 继承表示 : C++ 中继承可以使用 ":" 符号 , 格式为 & ...

  5. 初入c++(六)虚函数实现多态,虚析构函数,虚函数表和多态实现机制,纯虚函数。

    1.c++多态的概念以及用途. 1.1虚函数实现多态 通过基类指针只能够访问派生类的成员变量,不能够访问派生类的成员函数. 解决问题的办法:使用虚函数(virtual function),只需要在函数 ...

  6. C++多态虚函数/纯虚函数demo

    #include <iostream> using namespace std;class A //A是一个抽象类,不能new A直接实例化. { public:virtual void ...

  7. C++ 虚函数 纯虚函数 抽象类 代码示例

    其中抽象类指的是在类的定义中出现了纯虚函数,导致无法实例化,. 代码:头文件 #include "stdafx.h"using namespace std;class Person ...

  8. 虚函数 纯虚函数 虚基类说明

    原文:http://www.cnblogs.com/ms-frank/archive/2008/01/16/1041310.html 虚基类 在说明其作用前先看一段代码 [cpp] view plai ...

  9. 38.【C++ 虚函数 纯虚函数 虚基类 (最全详解)】

    虚函数.虚基类.纯虚函数 (一).虚函数 1.什么是虚函数: 2.虚函数的格式: 3.关于虚函数的注意事项: 4.虚函数的作用: 5.虚函数访问格式 6.虚函数的各种疑难杂症 [当指针是基类.但虚函数 ...

最新文章

  1. SPIFFS文件系统移植–基于STM32F407
  2. 全球及中国磁性分离头滑轮行业发展潜力与投资策略分析报告2022版
  3. python replace_DF.replace介绍
  4. 网易云信联合墨刀,邀你参加【产品设计狂欢节】!
  5. 如何正确的关闭 MFC 线程
  6. NPOI读写Excel sheet操作
  7. 操作系统swap对redis的性能的影响以及解决方案
  8. vue学习(十五) 过滤器简单实用
  9. kingroot android 7,KingRoot全球实现Android 7.0一键 Root
  10. NAT- STUN和TURN简介
  11. 计算机专业论文周记20篇,毕业论文工作周记6篇
  12. 银行网站 ca服务器的安装,建行网银CA认证系统建设案例介绍
  13. mac 磁盘分区 diskutil命令
  14. 笔记本CPU处理器HQ,H,U,M,型号之间的区别
  15. day1------安装部署k8s之完成(3)
  16. ele饿了么表单验证的校验提示突破v-if的限制
  17. Doris export任务概率性cancelled第二种情况
  18. 物联网卡无法激活使用的原因
  19. linux下输入ls显示时间格式,【Linux基础】linux下修改ls显示的时间格式
  20. 如何保障云上数据安全?一文详解云原生全链路加密

热门文章

  1. Beyond Compare 4右键菜单缺失问题
  2. HP电脑热键无法进入笔记本电脑BIOS解决方法
  3. python 读取图片数据
  4. PHP开发的简洁的导航网站源码多种主题风格切换
  5. 获得淘宝app商品详情原数据 API 返回值说明(item_get_app-淘宝app商品详情原数据)
  6. SPSS学习系列之SPSS Modeler的功能特性(图文详解)
  7. ogg源端mysql添加trandata_oracle ogg golden gate 安装与配置
  8. 六级经典范文之图画类文章模板句型
  9. 常用差分逻辑电平简介
  10. python进阶练习题:简单有趣#301:跳绳游戏【难度:2级】--景越Python编程实例训练营,不同难度Python习题,适合自学Python的新手进阶