下面通过一个例子来说明纯虚函数的定义方法

在这个类当中,我们定义了一个普通的虚函数,并且也定义了一个纯虚函数。那么,纯虚函数是什么呢??从上面的定义可以看到,纯虚函数就是没有函数体,同时在定义的时候,其函数名后面要加上“= 0”

纯虚函数的实现原理
本节从虚函数表的角度来说明纯虚函数的实现原理。

上面就是我们在前面课程讲到的多态的实现原理,在讲这一部分的时候,讲到了虚函数表以及虚函数表指针。如果我们定义了Shape这样的类,那么,Shape类当中,因为有虚函数和纯虚函数,所以,它一定有一个虚函数表,当然,也就一定有一个虚函数表指针。如果是一个普通的虚函数,那么,在虚函数表中,其函数指针就是一个有意义的值;如果是一个纯虚函数,那么,在虚函数表中,其函数指针的值就是0。也就是说,在虚函数表当中,如果是纯虚函数,那么就实实在在的写上0,如果是普通的虚函数,那就肯定是一个有意义的值。通过对纯虚函数的讲解,大家也一定会发现:纯虚函数也一定是某个类的成员函数,那么,包含纯虚函数的类也叫作什么呢?我们把包含纯虚函数的类称之为抽象类。比如刚刚举的Shape类当中就含有一个计算周长的纯虚函数,那么,我们就说这个Shape类是一个抽象类。大家可以想一想,如果我们使用Shape这个类去实例化一个对象,那么这个对象实例化之后,如果想要去调用纯虚函数(比如要去调用这个计算周长的纯虚函数),那怎么去调用呢???我们说,显然是无法调用的。所以,我们得出一个结论:对于抽象类来说,C++是不允许它去实例化对象的。也就是说,抽象类无法实例化对象。那么,如果我们强行写成如下形式:

比如上面的,从栈中或者堆中去实例化一个对象,此时,如果我们去运行程序的话,计算机就会报错。而且,不仅如此,对于抽象类的子类也可以是抽象类。比如:我们如果定义一个Person的类如下:

因为人是要工作的,所以定义了一个work()函数,同时还定义了一个打印信息的函数。由于人比较抽象,所以也不知道工作要做啥,所以就定义work()为纯虚函数,同时,也不知道该打印啥信息,所以也定义成了纯虚函数。当我们使用Worker这个类去继承Person类的时候,我们可以想象一下,对于工人来说,其工种是非常多的,单单一个工人,我们倒是可以一些他的信息(比如:这个工人的名字,工号等等),但是,这个工人是什么工作,具体是做什么的,我们也没有办法清晰明了的描述出来,所以这个时候,我们可以也把它定义成一个纯虚函数,如下所示。此时,这个Worker类作为Person的子类来说,它也是一个抽象类。

当我们明确了这个工人是什么工种(比如他是一名清洁工),清洁工这个类继承了Worker类(清洁工也是工人的一种),那么work()这个函数就有了一个明确的定义了(比如:他的工作就是扫地,我们可以将其打印出来),如下图所示。那么,此时,我们就可以使用清洁工(Dustman)这个类去实例化对

到此,我们需要强调说明一点的是:对于抽象类来说,它无法实例化对象,而对于抽象类的子类来说,只有把抽象类中的纯虚函数全部实现之后,那么这个子类才可以实例化对象。

纯虚函数和抽象类的代码实践
题目描述:

/* ************************************************ */

/* 纯虚函数和抽象类

1. Person类,成员函数:构造函数,虚析构函数,纯虚函数work(),数据成员:名字 m_strName

2. Worker类,成员函数:构造函数,work(),数据成员:年龄m_iAge

3. Dustman类,成员函数:构造函数,work()

*/

/* ************************************************ */

程序框架:

首先,我们来验证一下,含有纯虚函数的类,即抽象类能否实例化对象

头文件(Person.h)

#ifndef PERSON_H
#define PERSON_H#include <string>
using namespace std;
class Person
{
public:Person(string name);virtual void work() = 0; //定义函数work()为纯虚函数virtual ~Person() { }
private:string m_strName;
};#endif

源程序(Person.cpp)

#include "Person.h"Person::Person(string name)
{m_strName = name;
}

我们看到Person.h文件中定义了一个纯虚函数work(),即此时Person这个类是一个抽象类。接下来我们在main函数中去实例化一个Person类的对象看看情况如何?

主调程序(demo.cpp)

#include <stdlib.h>#include "Person.h"using namespace std;int main()
{Person person("Zhangsan");system("pause");return 0;
}

此时,我们调试一下程序(F7)看一看结果如何?运行结果如下:

我们可以看到错误提示:”Person”是一个抽象类,不能实例化。当我们双击这一行错误提示行的时候,箭头就会指向程序代码中的main函数中的实例化语句。

接着,我们看一看抽象类的子类是否能够实例化?

我们使用Worker这个类来继承Person类,如下:

头文件(Worker.h)

#ifndef WORKER_H
#define WORKER_H#include "Person.h"
class Worker:public Person
{
public:Worker(string name, int age);
private:int m_iAge;
};#endif

源程序(Worker.cpp)

#include <iostream>
#include "Worker.h"using namespace std;Worker::Worker(string name, int age):Person(name)
{m_iAge = age;
}

我们看到,在Worker这个类当中,我们并没有对work()这个函数做特别的处理,而是从Person类中完全继承下来了。由于Person类中的work()函数是一个纯虚函数,那么这就导致Worker这个类也变成了一个抽象类。那么,此时我们在main函数中去实例化一个Worker类的对象的话,结果如何呢?

主调程序(demo.cpp)


#include <iostream>
#include <stdlib.h>#include "Person.h"
#include "Worker.h"using namespace std;int main()
{Worker worker("ZhangSan", 30);system("pause");return 0;
}

此时,我们调试一下程序(F7)看一看结果如何?运行结果如下:

我们可以看到错误提示:”Worker”是一个抽象类,不能实例化。当我们双击这一行错误提示行的时候,箭头就会指向程序代码中的main函数中的实例化语句。

接下来,我们在Worker这个类中,对work()函数进行实现,然后再实例化一个Worker类对象,看一看结果又是如何?

头文件(Worker.h)


#ifndef WORKER_H
#define WORKER_H#include "Person.h"
class Worker:public Person
{
public:Worker(string name, int age);virtual void work();
private:int m_iAge;
};#endif

我们看到对于Worker这个类来说,其中也有一个work()函数。我们来看一看Worker.cpp文件

源程序(Worker.cpp)


#include <iostream>
#include "Worker.h"using namespace std;Worker::Worker(string name, int age):Person(name)
{m_iAge = age;
}void Worker::work()
{cout << "work()" << endl;
}

在这里,我们看到,在Worker.cpp中对work()这个函数进行了实现,此时我们再来实例化Worker对象如下:

主调程序(demo.cpp)


#include <iostream>
#include <stdlib.h>#include "Person.h"
#include "Worker.h"using namespace std;int main()
{Worker worker("ZhangSan", 30);system("pause");return 0;
}

此时,我们调试一下程序(F7)看一看结果如何?运行结果如下:

从结果看到,此时计算机编译通过。这样,也就从另一个角度说明了,Worker这个类虽然继承自抽象类Person类,但此时Worker类中已经没有了纯虚函数,但凡是虚函数,也已经被实现了。

从上面我们可以看到:如果Worker类中的work()函数也不进行实现,那么Worker这个类仍然是一个抽象类,也就不能进行实例化,此时,就待依赖Worker的子类来实现纯虚函数,从而就将此重任交给了清洁工(Dustman)这个类。那么,往往这种情况是存在的,因为对于人类来说,劳动这个函数很抽象,不知道该如何劳动,而到了Worker这个类中,劳动仍然比较抽象,因为我们虽然知道其是一个工人,但工人的工种有很多,工种不同,其具体劳动也不是不一样的,所以在Worker这个类当中,对work进行实现,往往显得也不太合适。那么,更多情况下,是在更具体的类中去实现work这个函数。比如说,在清洁工(Dustman)这个类中,工作就已经很明确了,他的工作就是扫地,所以对work进行实现的时候,就打印出“扫地”就行了,如下:

头文件(Worker.h)


#ifndef WORKER_H
#define WORKER_H#include "Person.h"
class Worker:public Person
{
public:Worker(string name, int age);
private:int m_iAge;
};#endif

源程序(Worker.cpp)


#include <iostream>
#include "Worker.h"using namespace std;Worker::Worker(string name, int age):Person(name)
{m_iAge = age;
}

头文件(Dustman.h)


#ifndef DUSTMAN_H
#define DUSTMAN_H#include "Worker.h"class Dustman:public Worker
{
public:Dustman(string name, int age);virtual void work();
};
#endif

源程序(Dustman.cpp)


#include "Dustman.h"
#include <iostream>
using namespace std;
Dustman::Dustman(string name, int age):Worker(name,age)
{}void Dustman::work()
{cout << "扫地" << endl;
}

主调程序(demo.cpp)


#include <stdlib.h>
#include "Dustman.h"
#include "Person.h"
#include "Worker.h"using namespace std;int main()
{Dustman dustman("ZhangSan", 30);system("pause");return 0;
}

此时,我们调试一下程序(F7)看一看结果如何?运行结果如下:

从结果看到,此时计算机编译通过。从而我们可以得到如下结论:对于一个含有纯虚函数的类(抽象类)来说,其无法进行实例化。
————————————————
版权声明:本文为CSDN博主「yuanchunsi」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yuanchunsi/article/details/78833899

C++系列(纯虚函数和抽象类)相关推荐

  1. c++ 纯虚函数和抽象类那些事(一)

    1.纯虚函数与抽象类 C++中的纯虚函数(或抽象函数)是我们没有实现的虚函数!我们只需声明它!通过声明中赋值0来声明纯虚函数! 纯虚函数:没有函数体的虚函数 抽象类:包含纯虚函数的类 /*** @br ...

  2. C++纯虚函数和抽象类

    基本概念 纯虚函数和抽象类 纯虚函数是一个在基类中说明的虚函数,但是在基类中没有定义,要求任何派生类都定义自己的版本 纯虚函数为个派生类提供一个公共界面(接口的封装和设计.软件模块功能的划分) 纯虚函 ...

  3. C++基本概念复习之二:多重继承、虚继承、纯虚函数(抽象类)

    一.多重继承: #include <iostream> using namespace std; class Horse { public: Horse(){cout<<&qu ...

  4. C++之纯虚函数和抽象类

    纯虚函数和抽象类 1.基本概念 2.案例 #include <iostream> using namespace std;////面向抽象类编程(面向一套预先定义好的接口编程)//解耦合 ...

  5. C++纯虚函数与抽象类

    纯虚函数 1.1纯虚函数是在声明虚函数时被"初始化"为0的函数.声明纯虚函数的一般形式为: virtual 函数类型 函数名 (参数列表) =0; 如 virtual float ...

  6. 9-2:C++多态之纯虚函数和抽象类以及接口继承和实现继承

    文章目录 (1)纯虚函数和抽象类的概念 (2)抽象类的意义 (3)接口继承与实现继承 (1)纯虚函数和抽象类的概念 如果一个类的虚函数后面写上=0,同时不写它的实现,那么这样的虚函数称之为纯虚函数,包 ...

  7. C++ 虚函数,纯虚函数,抽象类整理

    抽象类,类中包含纯虚函数的为抽象类,其中抽象类的子类必须实现抽象类的纯虚函数方法. 抽象类无法实例化 虚函数,子类可以实现或者不实现该方法都可以 如果父类调用子类的基类指针时,有虚函数的则使用子类的实 ...

  8. c/c++入门教程 - 2.4.7 多态、函数地址晚绑定(重写,虚函数,纯虚函数,抽象类,虚析构,纯虚析构)

    目录 4.7 多态 4.7.1 多态的基本概念(超级重要) 4.7.2 多态的原理刨析(超级重要) 4.7.2 多态案例一:计算器类 4.7.3 纯虚函数和抽象类 4.7.4 多态案例二 - 制作饮品 ...

  9. C++ 纯虚函数与抽象类

    1.虚函数 1.1 虚函数简介 可以毫不夸张地说虚函数是C++最重要的特性之一,我们先来看一看虚函数的概念. 在基类的定义中,定义虚函数的一般形式为: virtual 函数返回值类型 虚函数名(形参表 ...

  10. cc32a_demo-32dk2j_cpp_纯虚函数与抽象类-txwtech

    //32dk2j_cpp_纯虚函数与抽象类cc32a_demo-txwtech //纯虚函数是用来继承用的 //纯虚函数 //抽象类-抽象数据类型 //*任何包含一个或者多个纯虚函数的类都是抽象类 / ...

最新文章

  1. Axure 全局辅助线(转)
  2. ftp 信息服务器日常维护,Web Ftp Mail服务器的日常管理与维护
  3. 阿里达摩院科学家,3年造出小蛮驴!量产物流机器人,完全自动驾驶,4度电跑100公里...
  4. 第一次CM--CosH.2
  5. 使用 VS2013 Update 4 编译 Notepad++ 6.8.1
  6. 神策数据丨九大行业数字化经营指南集锦,值 100% 收藏
  7. .NET Core 3.1通用主机原理及使用
  8. 分享一个文件上传工具类
  9. LeetCode 2002. 两个回文子序列长度的最大乘积(状态压缩+枚举状态子集+预处理)
  10. 9 WM层面 临时仓储类型的仓位 主数据不存在
  11. GIL、进/线程池、同/异步、阻/非阻塞
  12. java家谱树_青锋家谱系统-基于springboot+orgtree的青锋家谱树管理系统
  13. PAT 7-14 公路村村通
  14. 负债均衡(三)下载安装Nginx
  15. WebLogic下载地址(各版本)
  16. python实现MD5加密工具
  17. STL-Intelligent IME
  18. “.NET研究”专访微软MVP衣明志:走进ASP.NET MVC 2框架开发
  19. 错误1919配置ODBC数据源时发生错误Visio database samples,ODBC错误6:部件在注册
  20. 去除CSDN博客图片中的水印

热门文章

  1. C#编程:常用数学函数
  2. 看代码,学strings包
  3. 【Python讲义】WEEK 8
  4. 测试网络连接速度 http://www.phoenixtv.com.cn/home/fhkp/testspeed.htm
  5. Linux内核启动过程和Bootloader
  6. 使用keras框架训练神经网络时显卡内存使用很大很大的解决方案
  7. 开源免费的私有聊天软件 Akaxin
  8. Photoshop精讲精练笔记
  9. 2019年为android开发准备的面试题(含答案)
  10. hostapd_cli 使用命令