整理摘自https://blog.csdn.net/ithomer/article/details/6031329

1. 申明格式

  1. class CShape
  2. {
  3. public:
  4. virtual void Show()=;
  5. };

在普通的虚函数后面加上"=0"这样就声明了一个pure virtual function.

2. 何时使用纯虚函数?

(1)当想在基类中抽象出一个方法,且该基类只做能被继承,而不能被实例化;
(2)这个方法必须在派生类(derived class)中被实现;
  如果满足以上两点,可以考虑将该方法申明为pure virtual function.

3. 举例说明

(1)不可实例化含有虚函数的基类

我们来举个例子,我们先定义一个形状的类(Cshape),但凡是形状我们都要求其能显示自己。所以我们定义了一个类如下:

  1. class CShape
  2. {
  3. virtual void Show(){};
  4. };

但没有CShape这种形状,因此我们不想让CShape这个类被实例化,我们首先想到的是将Show函数的定义(实现)部分删除如下:

  1. class CShape
  2. {
  3. virtual void Show();
  4. };
当我们使用下面的语句实例化一个CShape时:
CShape cs;  //这是我们不允许的,但仅用上面的代码是可以通过编译(但link时失败)。
 
怎样避免一个CShape被实例化,且在编译时就被发现?
答案: 使用pure virtual function.
  1. class CShape
    {
  2. public:
  3. virtual void Show()=;
  4. };

当实例化CShape cs 后,会报错:

error: cannot declare variable ‘cs’ to be of abstract type ‘CShape’
CShape cs;
              ^
note: because the following virtual functions are pure within ‘CShape’:
class CShape
          ^
note: virtual void CShape::Show()
virtual void Show()= 0;

^

(2)派生类中堆基类中虚函数的实现

        我们再来看看被继承的情况,我们需要一个CPoint2D的类,它继承自CShape.它必须实现基类(CShape)中的Show()方法。
        其实使用最初的本意是让每一个派生自CShape的类,都要实现Show()方法,但时常我们可能在一个派生类中忘记了实现Show(),为了避免这种情况,pure virtual funcion发挥作用了。
  1. class CShape
  2. {
  3. public:
  4. virtual void Show()= ;
  5. };
  6.  
  7. class CPoint2D: public CShape
  8. {
  9. public:
  10.  
  11. void Msg()
  12. {
  13. printf("CPoint2D.Msg() is invoked.\n");
  14. }
  15. /*
  16. void Show()
  17. {
  18. printf("Show() from CPoint2D.\n");
  19. }
  20. */
  21. };

当实例化 CPoint2D p2d时,报错

error: cannot declare variable ‘p2d’ to be of abstract type ‘CPoint2D’
CPoint2D p2d;
                ^
note: because the following virtual functions are pure within ‘CPoint2D’:
class CPoint2D: public CShape
         ^
note: virtual void CShape::Show()
virtual void Show()= 0;
                  ^

我们预防了在派生类中忘记实现基类方法。如果不在派生类的中实现在Show方法,编译都不会通过。

以下为完整代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. using namespace std;
  4.  
  5. class CShape
  6. {
  7. public:
  8. virtual void Show()= ;
  9. };
  10.  
  11. class CPoint2D: public CShape
  12. {
  13. public:
  14.  
  15. void Msg()
  16. {
  17. printf("CPoint2D.Msg() is invoked.\n");
  18. }
  19.  
  20. void Show()
  21. {
  22. printf("Show() from CPoint2D.\n");
  23. }
  24. };
  25.  
  26. int main()
  27. {
  28. CPoint2D p2d;
  29. p2d.Msg();
  30. CPoint2D *pShape = &p2d;
  31. pShape -> Show();
  32. return ;
  33. }
  34.  
  35. /* Output:
  36. CPoint2D.Msg() is invoked.
  37. Show() from CPoint2D.
  38. */

[C++基础] 纯虚函数的更多相关文章

  1. C++基础(纯虚函数与抽象类)

    C++基础之纯虚函数与抽象类 引言 纯虚函数在C++编程中的地位很重要,其关联到了设计模式中"接口"的概念. 语法 纯虚函数的语法: 1.  将成员函数声明为virtual 2.  ...

  2. C++学习基础十二——纯虚函数与抽象类

    一.C++中纯虚函数与抽象类: 1.含有一个或多个纯虚函数的类成为抽象类,注意此处是纯虚函数,而不是虚函数. 2.如果一个子类继承抽象类,则必须实现父类中的纯虚函数,否则该类也为抽象类. 3.如果一个 ...

  3. C++基础知识 基类指针、虚函数、多态性、纯虚函数、虚析构

    一.基类指针.派生类指针 父类指针可以new一个子类对象 二.虚函数 有没有一个解决方法,使我们只定义一个对象指针,就可以调用父类,以及各个子类的同名函数? 有解决方案,这个对象指针必须是一个父类类型 ...

  4. C++语言基础(13)-抽象类和纯虚函数

    一.基本语法 在C++中,可以将虚函数声明为纯虚函数,语法格式为: ; 纯虚函数没有函数体,只有函数声明,在虚函数声明的结尾加上=0,表明此函数为纯虚函数. 最后的=0并不表示函数返回值为0,它只起形 ...

  5. C++基础 (7) 第七天 多态的原理 纯虚函数和抽象类 依赖倒置原则

    1 昨日回顾 2 多态的原理 1 要有继承 2 要有子类重写父类的虚函数 3 父类指针(或者引用)指向子类对象 (动态联编 虚函数表 3 证明vptr指针的存在 4 vptr指针在构造父类的时候是分步 ...

  6. C++基础--虚函数和纯虚函数

    虚函数的一种重要的应用是在子类重写父类方法上,一般都是在父类中声明的时候用关键字virtual修饰. 在C++中,一个父类的对象指针是可以指向子类的实例化对象,这个时候可以用该对象指针来访问父类的成员 ...

  7. C++复习:纯虚函数和抽象类

    纯虚函数和抽象类 1基本概念 2抽象类案例   3抽象类在多继承中的应用 C++中没有Java中的接口概念,抽象类可以模拟Java中的接口类.(接口和协议) 3.1有关多继承的说明 工程上的多继承 被 ...

  8. 谈谈c++纯虚函数的意义!

    纯虚函数的存在有什么意义呢?相信大学假设有c++这么课程.在讲到纯虚函数时,必然会讲到纯虚函数是面向接口编程的基础. 如今和大家分享下纯虚函数设计的原由.目的.产生的效果. 现代软件project很庞 ...

  9. c++-纯虚函数和抽象类

    纯虚函数和抽象类 C面向接口编程和C多态 函数类型语法基础 函数指针做函数参数(回调函数)思想剖析 函数指针做函数参数两种用法(正向调用.反向调用) 纯虚函数 抽象类 抽象类基本概念 抽象类在多继承中 ...

随机推荐

  1. 洛谷 P1417 烹调方案 题解

    题面 这道题是一道典型的排序dp a[i]−b[i]∗(t+c[i])+a[j]−b[j]∗(t+c[i]+c[j]) a[j]−b[j]∗(t+c[j])+a[i]−b[i]∗(t+c[i]+c[j ...

  2. 文件的三种打开方式及with管理文件上下文

    文件的三种打开方式及with管理文件上下文 一.文件的三种打开方式 1.1 只读 f = open(r'D:\pycharm\yjy\上海python学习\456.txt','r',encoding= ...

  3. 自己动手实现一个html2canvas

    前言 昨天写了新手引导动画的4种实现方式,里面用到了 html2canvas 于是就顺便了解了一下实现思路. 大概就是 利用 svg 的 foreignObject 标签, 嵌入 dom, 最后再利用 ...

  4. 095、如何创建Swarm集群?(Swarm02)

    参考https://www.cnblogs.com/CloudMan6/p/7862254.html   本节我们将创建三节点的swarm集群(操作系统Ubuntu 16.04 ,Docker 版本均 ...

  5. MySQL基础入门之常用命令介绍

    mysql命令介绍 mysql 是数据库管理命令 通过mysql --help来查看相关参数及使用说明 mysql --help                #mysql数据库管理命令 Usage: ...

  6. webstorm 如何去掉下划线

    当前webstorm版本:2018.3.5 百度了也没找到解决办法,最终结合了和群友的给的位置,找到了修改地方,只能怪版本迭代太快了,要适应 右上角Effects点掉就可以了

  7. Adobe cc2019全家桶(免破解直接安装版)

    图片来源:Adobe官网 此次整理了Adobe cc2019的全家桶,全部为免破解,直接安装即可使用版本,对一些小白来说,值得推荐. 下载方式:找到下面你需要的Adobe软件,公众号内回复对应的关键词 ...

  8. Linux查看及设置系统时区

    一.什么是时区呢? 关于时区的概念,其实初中地理课已经涉及,很多人都多少了解一些,可能只是细节搞不太清楚.为什么会将地球分为不同时区呢?因为地球总是自西向东自转,东边总比西边先看到太阳,东边的时间也总 ...

  9. Ubuntu换阿里云源

    sudo -s cd /etc/apt gedit source.list deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted u ...

  10. windows pip使用国内源

    在这里我使用清华源来做示范 win+R 打开用户目录%HOMEPATH%,在此目录下创建 pip 文件夹,在 pip 目录下创建 pip.ini 文件, 内容如下, 在pip文件夹里新建的pip.in ...