在继承关系中,虚函数、虚析构函数、虚基类中使用的关键字virtual都是在告诉编译器,此处要进行特殊处理:

虚函数:函数重写时的要求编译器动态绑定来实现多多态 ;

虚析构函数:当基类指针指向在堆内实现的派生类的动态对象时,virtaul声明的基类析构函数是告诉编译器,还要调用派生类的析构函数。

虚基类:当派生类有多重继承和多继承时,在继承链上有两个子类继承自同一基类时,此两个子类作为基类再次派生出一个类,若只想保存这两个子类的基类的一个实例,需用virtual来声明继承关系,编译器对虚基类只实现一个实例,从而避免二义性。

1 虚函数

面向对象的在继承时要实现动态多态,需要用关键字virtual告诉编译器,由编译器在编译时生成一个虚函数表,程序运行时实现每个对象通过一个自动添加的函数指针来动态绑定一个函数去实现多态:

#includeclass CShape{public:virtual double Area(){cout<Area()<Area()<

2 虚析构函数

在实现多态时,如果是由基类指针指向在堆上动态创建派生对象时,如果delete此虚类指针,则基类的析构函数被调用,并不会调用派生类的析构函数,如果派生类中有在堆上动态创建的数据时,则会出现内存泄露。C++编译器的做法时,如果基类的析构函数前面有用virtual修饰,编译器会自动去调用派生类的析构函数(实现动态绑定,如果其它成员函数的动态绑定一样),做内存释放的工作。

如果某个类不包含虚函数,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。因为它会为类增加一个虚函数表,使得对象的体积翻倍,还有可能降低其可移植性。实际上,很多人这样总结:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。

虚析构函数是为了解决这样的一个问题:基类的指针指向派生类对象,并动态调用派生类的析构函数。

#include using namespace std;class CSon{public:~CSon(){cout<

3 虚基类

当在多条继承路径上有一个公共的基类,在这些路径中的某几条汇合处,这个公共的基类就会产生多个实例(或多个副本),若只想保存这个基类的一个实例,可以将这个公共基类说明为虚基类。

如果将这种多继承和多重继承画成图形关系,会有菱形的图案出现,称为菱形继承:

如图,子类D最后会接受分别来自B和C的同一个或多个相同拷贝,从而产生了多个拷贝,即不止一次的通过多个路径继承类在内存中创建了基类成员的多份拷贝。而这些是B和C从父类继承而来,所以D类该继承B还是C传下来的,还是都接受呢?这样就产生歧义(二义性),虚基类的基本原则是在内存中只有基类成员的一份拷贝。这样,通过把基类继承声明为虚拟的(virtual限定符),就只能继承基类的一份拷贝,从而消除歧义。

#includeclass base { protected:  int a; public:  base(){ cout <

输出结果为:0123,如果省略掉其中的关键字virtual,则输出01023,可以看出,构造函数有重复调用。

-End-

c++ map 析构函数_C++|类继承关系中的虚函数、虚析构函数、虚基类相关推荐

  1. 虚函数之定义一个基类Shape,在此基础上派生出Rectangle和Circle再使用Rectangle类创建一个派生类Square。

    定义一个基类Shape,在此基础上派生出Rectangle和Circle,二者都有getArea( )函数计算对象的面积,再使用Rectangle类创建一个派生类Square.将getArea()改造 ...

  2. 使用IntelliJ IDEA看源码的时候,如何在优雅的查看类继承关系...【看这篇就够了】

    导读 在公司 ,特别对于我们刚入职公司,在看一个新系统的时候,特别是这个项目已经搭建的不错的时候,我们需要去熟悉这个系统,就像我们去阅读源码一样,去理解这个系统的大体功能,类之间的关系,之间的继承. ...

  3. c++中的虚特性(虚基类、虚函数、纯虚函数)

    1. 虚基类 1.1 虚基类作用 为了解决多继承时的命名冲突和冗余数据问题,使得派生类中只保留一份间接基类的成员. 其本质是是让某个类做出声明,承诺愿意共享它的基类.其中,这个被共享的基类就称为虚基类 ...

  4. 虚函数、纯虚函数、虚基类、抽象类、虚函数继承、虚继承

    虚函数:虚函数是C++中用于实现多态(polymorphism)的机制.核心理念就是通过基类访问派生类定义的函数.是C++中多态性的一个重要体现,利用基类指针访问派生类中的成员             ...

  5. 虚函数、纯虚函数、虚继承、多继承

    来源:http://www.tnove.com/?p=57 C++的一个特征是多太,其中多态主要表现在 1.编译时多态  函数overload实现 2.运行是多态  虚函数override实现 其中虚 ...

  6. 析构函数和虚函数、纯虚函数

    置于"-"是析构函数:析构函数因使用"-"符号(逻辑非运算符),表示它为逆构造函数,加上类名称来定义.  析构函数也是特殊的类成员函数,它没有返回类型,没有参数 ...

  7. 构造函数不可以声明为虚函数,析构函数可以声明为虚函数

    构造函数不能声明为虚函数,而析构函数可以声明为虚函数,在有的情景下析构函数必须声明为虚函数.  不建议在构造函数和析构函数里调用虚函数. 构造函数不能声明为虚函数的原因? 构造一个对象时,必须知道对象 ...

  8. c语言中虚函数和纯虚函数,C++ 虚函数和纯虚函数的区别

    首先:强调一个概念 定义一个函数为虚函数,不代表函数为不被实现的函数. 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数. 定义一个函数为纯虚函数,才代表函数没有被实现. 定义纯虚函数是为了实 ...

  9. c语言中虚函数和纯虚函数,虚函数和纯虚函数的区别是什么?

    虚函数和纯虚函数的区别:1.纯虚函数只有定义,没有实现:而虚函数既有定义,也有实现的代码.2.包含纯虚函数的类不能定义其对象,而包含虚函数的则可以. 相关推荐:<C++视频教程> 虚函数( ...

最新文章

  1. numpy 中的三个特别的索引操作 c_, r_, s_
  2. 【MM配置】Batch Determination 批次决定
  3. append 降低数组位数_4.有序数组
  4. C# 使用int.TryParse,Convert.ToInt32,(int)将浮点类型转换整数时的区别
  5. 黑马程序员顺义校区php_黑马程序员:从PHP零基础到月薪11K为何送锦旗给班主任?...
  6. airflow 進行後端大數據中ETL處理(草稿)
  7. ubuntu 16.04 编译构建QEMU依赖的软件
  8. opencv 鼠标事件
  9. 代码审计:命令注入学习
  10. android tv webview,Android TV中WebView的按键响应问题
  11. java通过itext方法往pdf中插入图片(交互式pdf插入图片无法显示)
  12. 2021 年度程序员收入报告:字节跳动排名全球第 5!
  13. 日语截图翻译软件(百度ocr+python3+pyqt5)
  14. constantlayout布局
  15. 高数——定积分计算大法之换元法
  16. B2C电商项目(第十五天、秒杀后端、异步下单、防止恶意刷单、防止重复秒杀、下单接口隐藏、下单接口限流 )
  17. “工资倒挂”成常态,你介意新员工比你工资高吗?
  18. 【浏览器被劫持解决方案】https://www.hao123.com/?tn=9762xxxx2644_hao_pg
  19. nutch-2.1导入eclipse+mysql运行
  20. python基础知识点大全

热门文章

  1. service 层 拼接的html 代码如何直接返回_代码分层的设计之道
  2. python代码生成可执行程序_Python—脚本程序生成exe可执行程序(pyinstaller)
  3. ozf oracle,ORACLE EBS 简称大全
  4. excel不能编辑如何解锁_偷梁换柱之EXCEL编辑保护和VBA隐藏代码保护的解锁
  5. XXXXX CodeForces - 1364A(思维)
  6. Educational Codeforces Round 88 (Rated for Div. 2)(AB)
  7. matlab求迟滞,MATLAB PI迟滞模型问题
  8. 自定义按键_雷柏VT300S号称吃鸡鼠标,能够自定义10个编程按键
  9. idea 代码第一次上传git_如何使用IDEA将项目代码首次上传至GitHub,并持续推送?...
  10. codeforce 266c Below the Diagonal 矩阵变换 (思维题)