相关文章推荐
才高八斗的玉米  ·  解决spring ...·  1 年前    · 
曾经爱过的机器猫  ·  python - pandas 之 ...·  1 年前    · 
痴情的拖把  ·  JAva fx提示错误: 缺少 ...·  1 年前    · 

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

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

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

⑵抽象类的作用:

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

(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模板多态

所谓的动态和静态区分是另一种基于绑定时间的多态分类,严格来说,重载是编译时多态,即静态多态,根据不同类型函数编译时会产生不同的名字如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 (参数列表);

为什么要引入抽象基类和纯虚函数?主要目的是为了实现一种接口的效果。抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层。 ⑴抽象类的定义:带有纯虚函数的类为抽象类。 ⑵抽象类的作用: 抽象类的主要作用是将有关的操作作为结果接口组织在一个继承层次结构中,由它来为派生类提供一个公共的根,派生类将具体实现在其基类中作为接口的操......
虚函数为了重载和多态的需要,在基类 是有定义的,即便定义是空,所以子类 可以重写也可以不写基类 的此函数! 纯虚函数 在基类 是没有定义的,必须在子类 加以实现,很像java 的接口函数! 引入 原因:为了方便使用多态特性,我们常常需要在基类 定义虚函数。 class Cman public: virtual void Eat(){……}; void Move(); private: class CChild : public CMan public: virtual void Eat(){……}; private: CMan m_man; CChild m_chil
该资源是博主博客的源代码,博客上有详细讲解Qt/ C++ 关于 纯虚函数 抽象基类 原理讲解和示例用法解释,博客地址如下: https://blog.csdn.net/naibozhuan3744/article/details/94488200 其 编译环境为QtCreator4.5.0(qt5.9.4),用MinGW32位编译器编译。
为什么说虚函数是 C++ 最重要的特性之一呢,因为虚函数承载着 C++ 动态联编的作用,也即多态,可以让程序在运行时选择合适的成员函数。虚函数必须是类的非静态成员函数(且非构造函数),其访问权限是public。那么:  (1)为什么类的静态成员函数不能为虚函数?  如果定义为虚函数,那么它就是动态绑定的,也就是在派生类 可以被覆盖的,这与静态成员函数的定义(在内存 只有一份拷贝,
C++ 纯虚函数 详解 有时在基类 将某一成员函数定为虚函数,并不是基类本身的要求,而是考虑到派生类的需要,在基类 预留了一个函数名,具体功能留给派生类根据需要去定义。 纯虚函数 是在声明虚函数时被“初始化”为0的函数。声明 纯虚函数 的一般形式是 virtual 函数类型 函数名 (参数表列) = 0; 关于 纯虚函数 需要注意的几点: 纯虚函数 没有函数体; 最后面的“=0”并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是 纯虚函数 ”; 这是一个声明语句,最后应有分号。 纯虚函数 只有函数的名字而不具备函数的功能,不能被调用。它只是通知编译系统:“在这里声明一个虚函数,留待派
父类(基类,超类)派生出来子类(派生类)。 继承:有父亲类,有孩子类,就构成了层次关系。继承是面向对象程序设计的核心思想之一。 这种继承,要先定义一个父类。父类 定义一些公用的成员变量,成员函数。通过继承父类构建新的类:子类。所以写代码是,只需要写和子类相关的东西即可。子类一般会比父类更加庞大。 定义一个Human类: #pragma once #ifndef __HUMAN__ #define __HUMAN__ #incl
需要实例化类的虚函数必须有定义,而仅仅定义带有虚函数的类且虚函数没有实现,该类编译是可以通过的! 纯虚函数 出现在接口类 ,并赋值为0,不要为该函数分配函数地址,从而阻止类的实例化! 纯虚函数 是没有定义的,如果实现了也不是 纯虚函数 啦!      一般的成员函数可以只有声明,前提是在应用 不能调用该函数,否则会因找不到定义产生连接错误!      实例化类的虚函数必须有定义,原因如
纯虚函数 是指不必在基类 定义,但必须在派生类 被覆盖(override)的函数。通过新奇的“=0”语法可将虚函数声明为 纯虚函数 。例如: class Base { public: void f1(); // 不是虚函数 vi...
在基类 引入 虚函数的目的,是为了派生类(子类) 实现多态。 有些基类,不能够实例化,实例化没有意义,比如说你定义了一动物为基类,该基类实例化没有实际意义,还是抽象的,不存在的具体对象。 为此,在基类 引入 纯虚函数 ,这样,基类就不能被实例化了。 这样的类,被称作抽象类。
在某些类里声明纯虚析构函数很方便。 纯虚函数 将产生抽象类——不能实例化的类(即不能创建此类型的对象)。有些时候,你想使一个类成为抽象类,但刚好又没有任何 纯虚函数 。怎么办?因为抽象类是准备被用做基类的,基类必须要有一个虚析构函数, 纯虚函数 会产生抽象类,所以方法很简单:在想要成为抽象类的类里声明一个纯虚析构函数。  class awov {   public: 首先:强调一个概念 定义一个函数为虚函数,不代表函数为不被实现的函数。 定义它为虚函数是 为了允许用基类的指针来调用子类的这个函数 , 也就是 虚函数是指一个类 你希望重载的成员函数 ,当你用一个 基类指针或引用 指向一个子类对象的时候,调用一个虚函数时, 实际调用的是子类的版本。 定义一个函数为 纯虚函数 ,才代表函数没有被实现。 定义 纯虚函数 是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。 一、虚函数 1.虚函数定义 在基类 实现虚函
C++ 为什么要定义 抽象基类 ?        抽象类就是类里定义了纯虚成员函数的类。 纯虚函数 只提供了接口,并没有具体实现。抽象类不能被实例化,通常是作为基类供子类继承,子类 重写虚函数,实现具体的接口。 为什么要定义 抽象基类 呢?依我所见主要有以下原因: 1.最重要的原因是,可以将接口与实现分离。接口是软件产品最有价值的资源,设计接口比实现接口需要耗费更昂贵的成本。因此,要将接口保护起来,以免在...
已解决:Job for docker.service failed because the control process exited with error code. See “systemctl 我应该先看评论的,我的镜像得重新下载了。 MySQL 系统自带的数据库有哪些?每个数据库的作用是什么? 博主 我想问一下为什么我下载的最新版mysql时候四个库 没有world和demo