为什么要引入抽象基类和纯虚函数?
主要目的是为了实现一种接口的效果。

抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层。

⑴抽象类的定义:带有纯虚函数的类为抽象类。

⑵抽象类的作用:

抽象类的主要作用是将有关的操作作为结果接口组织在一个继承层次结构中,由它来为派生类提供一个公共的根,派生类将具体实现在其基类中作为接口的操作。所以派生类实际上刻画了一组子类的操作接口的通用语义,这些语义也传给子类,子类可以具体实现这些语义,也可以再将这些语义传给自己的子类。

(3)使用抽象类时注意:

抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。如果派生类中没有重新定义纯虚函数,而只是继承基类的纯虚函数,则这个派生类仍然还是一个抽象类。如果派生类中给出了基类纯虚函数的实现,则该派生类就不再是抽象类了,它是一个可以建立对象的具体的类。

抽象类是不能定义对象的。

一、纯虚函数定义

 纯虚函数是一种特殊的虚函数,它的一般格式如下:

  class <类名>

  {

  virtual <类型><函数名>(<参数表>)=0;

  …

  };

  在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用。

  纯虚函数可以让类先具有一个操作名称,而没有操作内容,让派生类在继承时再去具体地给出定义。凡是含有纯虚函数的类叫做抽象类。这种类不能声明对象,只是作为基类为派生类服务。除非在派生类中完全实现基类中所有的的纯虚函数,否则,派生类也变成了抽象类,不能实例化对象。

二、纯虚函数引入原因

    1、为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。

  2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔 雀等子类,但动物本身生成对象明显不合常理。

  为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;)。若要使派生类为非抽象类,则编译器要求在派生类中,必须对纯虚函数予以重载以实现多态性。同时含有纯虚函数的类称为抽象类,它不能生成对象。这样就很好地解决了上述两个问题。

例如,绘画程序中,shape作为一个基类可以派生出圆形、矩形、正方形、梯形等, 如果我要求面积总和的话,那么会可以使用一个 shape * 的数组,只要依次调用派生类的area()函数了。如果不用接口就没法定义成数组,因为既可以是circle ,也可以是square ,而且以后可能加上rectangle,等等.

三、相似概念

1、多态性  指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。C++支持两种多态性:编译时多态性,运行时多态性。  a.编译时多态性:通过重载函数实现  b 运行时多态性:通过虚函数实现。  2、虚函数  虚函数是在基类中被声明为virtual,并在派生类中重新定义的成员函数,可实现成员函数的动态重载  3、抽象类

  包含纯虚函数的类称为抽象类。由于抽象类包含了没有定义的纯虚函数,所以不能定义抽象类的对象。

四、其他

重载是不是多态?

第一种说法

  重载是一种是多态(如C++),有四种形式的多态:

  1.虚函数多态

  2模板多态

  3重载

  4转换

  所谓的动态和静态区分是另一种基于绑定时间的多态分类,严格来说,重载是编译时多态,即静态多态,根据不同类型函数编译时会产生不同的名字如int_foo和char_foo等等,以此来区别调用。故重载仍符合多态定义——通过单一标识支持不同特定行为的能力,只是重载属于静态多态,而不是通过继承和虚函数实现的动态多态。

第二种说法

  重载(overload)和多态无关,真正和多态相关的是覆盖(override)。

  当派生类重新定义了基类的虚拟方法后,基类根据赋给它的不同的派生类引用,动态地调用属于派生类的对应方法,这样的方法调用在编译期间是无法确定的。因此,这样的方法地址是在运行期绑定的(动态绑定)。

  重载只是一种语言特性,是一种语法规则,与多态无关,与面向对象也无关。

  不过针对所谓的第二种重载,有一个专门的名词--重写或重定义。重载与重写的区别就在于是否覆盖,重写一般多发生在不同的类且存在继承关系之间,而重载多是在一个类里或者一块代码段里。

C++中的重载

  函数重载:

  函数重载就是函数名称相同,但定义却不同。函数重载使得程序员可以将一系列的函数族定义为一个统一的界面,但是却可以处理不同类型数据或接受不同个数的参数。这实现了统一接口,不同定义的思想。

  流的重载:

  C++的流提取运算符>>和就插入运算符<<是C++类库提供的输入输出(I/O)操作符。系统与定义了输入流类istream和输出流类ostream,cin和cout分别是istream和ostream的对象。iostream头文件中已经对>>和<<进行了重载,使得它能用来输入/输出标准类型的数据。但如果是自己定义类型,就需要重载在这两个运算符,以便它们能输入/上岁数出该自定义类型。格式如下:

  流插入的重载:ostream &operator<<(ostream &,自定义类 &);

  流提取的重载:istream &operator>>(istream &,自定义类 &);

  运算符的重载:

  运算符的重在就是对运算符的重新定义,即一个运算符可以用于多种数据类型的运算中。运算符的重载在实际编程中使用很普遍,例如,“+”运算符既可以用于整数加,也可以用于浮点加,甚至是字符串的链接。格式如下:

  type operator sign (参数列表);

C++中为什么要引入抽象基类和纯虚函数?相关推荐

  1. C++引入抽象基类和纯虚函数的作用和目的

    为什么要引入抽象基类和纯虚函数? 主要目的是为了实现一种接口的效果. 原文链接:https://blog.csdn.net/weibo1230123/article/details/82014322 ...

  2. C++之抽象基类与纯虚函数

    // Vitual_Base.cpp : Defines the entry point for the console application. //抽象基类与纯虚函数#include " ...

  3. C++之继承探究(十):抽象基类与纯虚函数

    前文:C++之继承探究(九):多态的代价 抽象基类与纯虚函数   ♠\spadesuit♠ 纯虚函数:虚函数只有声明,函数体=0,就是一个纯虚函数,纯虚函数没有函数体,不需要实现.在子类里实现纯虚函数 ...

  4. C++ day24 继承(四)抽象基类,纯虚函数,protected

    文章目录 关键字protected(带来方便同时带来危险,最好不用) 抽象基类和纯虚函数(is-a关系用公有继承实现有时候也不太合适) 用圆和椭圆的笨拙派生为例,挑拨is-a和公有继承的搭档关系 替代 ...

  5. C++抽象基类和纯虚成员函数

    公共接口是指一系列成员函数的集合,支持该接口的类必须以合适的方式重新定义这些成员函数,否则就无法创建对象.在C++中,可以通过抽象基类来实现公共接口. 纯虚函数 纯虚成员函数的声明语法如下: virt ...

  6. 虚函数,虚基类 与纯虚函数 二

    虚函数    还是先看代码 class A { public:     void funPrint(){cout<<"funPrint of class A"<& ...

  7. 虚函数,虚基类 与纯虚函数 一

    正文 虚基类    在说明其作用前先看一段代码 class A { public:     int iValue; }; class B:public A { public:     void bPr ...

  8. 避免在派生类中重新定义基类的非虚函数

    我们都知道,在基类中定义虚函数的目的是允许派生类拥有相同接口却可以有不同的实现,通过对象的指针或引用来访问虚函数可以实现运行时的多态.这么说来,在派生类中重定义(override)虚函数是没有任何问题 ...

  9. C++中虚继承产生的虚基类指针和虚基类表,虚函数产生的虚函数指针和虚函数表

    本博客主要通过查看类的内容的变化,深入探讨有关虚指针和虚表的问题. 一.虚继承产生的虚基类表指针和虚基类表 如下代码:写一个棱形继承,父类Base,子类Son1和Son2虚继承Base,又来一个类Gr ...

最新文章

  1. 不要让海浪中奔腾的豪情任岁月摧折,不要让江风中许下的誓言随流水消逝
  2. 创建JPA工程时提示:at least one user library must be selected
  3. sql count用法_SQL学习笔记3:count(*)函数
  4. 阿里巴巴分布式事务利器Seata环境准备
  5. AxWebBrowser打开本地文件
  6. ERP项目管理的关键控制点
  7. 前端程序员 学习书籍推荐
  8. java b s用户管理系统_基于B/S的教务信息管理系统
  9. 三种计算机控制系统是,计算机控制系统3
  10. android怎么防8门神器,Android八门神器使用图文教程
  11. sandboxie游戏不能运行在虚拟环境中如何解决_Mac系统运行“exe”文件最简单的解决办法...
  12. 删除计算机硬盘中的文件,硬盘上数据如何彻底删除 硬盘上数据彻底删除方法【详解】...
  13. CC2530模块进行ZigBee实验小结
  14. 转载 | 在阿里做了3年多程序员,我究竟学到了什么?
  15. [附源码]Python计算机毕业设计SSM京津冀畅游网设计(程序+LW)
  16. OLE技术专题——第一讲:OLE概述
  17. js中call()方法的用法
  18. 二叉树面试题:前中序求后序、中后序求前序
  19. 浅显的mysql优化
  20. Python4.定义类及使用类,类的继承,抽象方法多态

热门文章

  1. wubantu18.04版,pycharm2.18.3.2永久破解来了,借鉴个位大神的教程破掉的,感谢各位大佬...
  2. Android.mk文件编写
  3. 7-20(排序) 奥运排行榜(25 分)
  4. 关于Combobox的多选和单选情况
  5. Centos之压缩和解压缩命令
  6. 云+网+端 技术架构
  7. Python 序列化
  8. HDOJ 3642 Get The Treasury(扫描线 + 线段树 + 离散化 立方体的并)
  9. 导出到Excel的操作
  10. 多线程pthread_join()的作用