#include <iostream>
using namespace std;
//线
class Line
{
public:
Line(float len);
virtual float area() = ;
virtual float volume() = ;
protected:
float m_len;
};
Line::Line(float len):
m_len(len)
{ } //矩形
class Rec: public Line
{
public:
Rec(float len, float width);
float area();
protected:
float m_width;
}; Rec::Rec(float len, float width):
Line(len), m_width(width)
{ } float Rec::area()
{
return m_len * m_width;
} //长方体
class Cuboid: public Rec
{
public:
Cuboid(float len, float width, float height);
float area();
float volume();
protected:
float m_height;
};
Cuboid::Cuboid(float len, float width, float height):
Rec(len, width), m_height(height)
{ } float Cuboid::area()
{
return * ( m_len*m_width + m_len*m_height + m_width*m_height);
}
float Cuboid::volume()
{
return m_len * m_width * m_height;
} //正方体
class Cube: public Cuboid
{
public:
Cube(float len);
float area();
float volume();
};
Cube::Cube(float len):
Cuboid(len, len, len)
{ } float Cube::area()
{
return * m_len * m_len;
}
float Cube::volume()
{
return m_len * m_len * m_len;
} int main()
{
Line *p = new Cuboid(, , );
cout<<"The area of Cuboid is " <<p->area()<<endl;
cout<<"The volume of Cuboid is " <<p->volume()<<endl; p = new Cube();
cout<<"The area of Cube is "<<p->area()<<endl;
cout<<"The volume of Cube is "<<p->volume()<<endl;
return ;
}

运行结果:
The area of Cuboid is 2200
The volume of Cuboid is 6000
The area of Cube is 1350
The volume of Cube is 3375

本例中定义了四个类,它们的继承关系为:Line --> Rec --> Cuboid --> Cube。

Line 是一个抽象类,也是最顶层的基类,在 Line 类中定义了两个纯虚函数 area() 和 volume()。

在 Rec 类中,实现了 area() 函数;所谓实现,就是定义了纯虚函数的函数体。但这时 Rec 仍不能被实例化,因为它没有实现继承来的 volume() 函数,volume() 仍然是纯虚函数,所以 Rec 也仍然是抽象类。

直到 Cuboid 类,才实现了 volume() 函数,才是一个完整的类,才可以被实例化。

可以发现,Line 类表示“线”,没有面积和体积,但它仍然定义了 area() 和 volume() 两个纯虚函数。这样的用意很明显:Line 类不需要被实例化,但是它为派生类提供了“约束条件”,派生类必须要实现这两个函数,完成计算面积和体积的功能,否则就不能实例化。

在实际开发中,你可以定义一个抽象基类,只完成部分功能,未完成的功能交给派生类去实现(谁派生谁实现)。这部分未完成的功能,往往是基类不需要的,或者在基类中无法实现的。虽然抽象基类没有完成,但是却强制要求派生类完成,这就是抽象基类的“霸王条款”。

抽象基类除了约束派生类的功能,还可以实现多态。请注意第 51 行代码,指针 p 的类型是 Line,但是它却可以访问派生类中的 area() 和 volume() 函数,正是由于在 Line 类中将这两个函数定义为纯虚函数;如果不这样做,51 行后面的代码都是错误的。我想,这或许才是C++提供纯虚函数的主要目的。

关于纯虚函数的几点说明

1) 一个纯虚函数就可以使类成为抽象基类,但是抽象基类中除了包含纯虚函数外,还可以包含其它的成员函数(虚函数或普通函数)和成员变量。

2) 只有类中的虚函数才能被声明为纯虚函数,普通成员函数和顶层函数均不能声明为纯虚函数。如下例所示:

C++ 虚函数实例的更多相关文章

  1. 一个C++的多态和虚函数实例

    类的说明: code: #include<iostream> #include<string> #define PAI 3.1415926 using namespace st ...

  2. c++特别要点:多态性与虚函数

    本来是准备在工厂模式中顺便整理.但粗略浏览了,内容还是很多,需要单独开一篇. 一.什么是多态性? 多态性可以概括为“一个接口,多种方法”. 多态与非多态的区别在于“成员函数调用地址的早绑定和晚绑定”. ...

  3. Delphi子类调用祖父类的虚函数

    因为看Delphi书的时候,就产生了疑惑.老讲调用父类虚函数,但是万一需要调用祖父虚函数怎么办?后来又经常在C++里看到,就更疑惑了 type TA = class procedure ShowMsg ...

  4. 静态成员函数与pthread_create,纯虚函数匹配使用实例

    最近在浏览朋友写的代码,发现有一个细节非常值得学习,在这里将代码贴出来简单分享一下: #ifndef THREAD_H_ #define THREAD_H_ #include <pthread. ...

  5. 匹夫细说C#:从园友留言到动手实现C#虚函数机制

    前言 上一篇文章匹夫通过CIL代码简析了一下C#函数调用的话题.虽然点击进来的童鞋并不如匹夫预料的那么多,但也还是有一些挺有质量的来自园友的回复.这不,就有一个园友提出了这样一个代码,这段代码如果被编 ...

  6. C++ 系列:虚函数

    Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...

  7. C#虚函数和接口的区别

    接口只能声明不能实现,虚函数可以. 接口:对外提供可以访问的函数叫接口.虚函数不需要被强制重写,其本身含有实现部分. 抽象类:指派了派生类必须实现的函数(纯虚函数),不然编译不通过. 虚函数的限制:  ...

  8. 为何JAVA虚函数(虚方法)会造成父类可以"访问"子类的假象?

      首先,来看一个简单的JAVA类,Base. 1 public class Base { 2 String str = "Base string"; 3 protected vo ...

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

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

随机推荐

  1. Docker | 第三章:Docker常用命令

    前言 上一章节,简单介绍了在CentOS下的Docker的安装过程,以及运行了一个官方提供的Hello,World镜像运行了第一个Docker.就像上一章中,验证Docker是否安装成功,我们执行的是 ...

  2. ElasticSearch java API 按照某个字段排序

    searchRequestBuilder.addSort("publish_time", SortOrder.DESC); 按照某个字段排序的话,hit.getScore()将会失 ...

  3. sql 删除字段 出错

    1. 删除字段:   ALTER TABLE TALE_NAME DROP COLUMN nn;   2.报错: 消息 5074,级别 16,状态 1,第 1 行对象'DF__WorkOrder__I ...

  4. wcf_消息通信模式(下) 双工通讯

    原文:[老老实实学WCF] 第十篇 消息通信模式(下) 双工 第十篇 消息通信模式(下) 双工 在前一篇的学习中,我们了解了单向和请求/应答这两种消息通信模式.我们知道可以通过配置操作协定的IsOne ...

  5. 【踩坑】遇到 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found) 报错

    今天在重做 iblog 客户端时,测试接口情况,发现了 org.apache.ibatis.binding.BindingException: Invalid bound statement (not ...

  6. 学习笔记:MDN的CSS

    HTML用于定义内容的结构和语义,CSS用于设计风格和布局. CSS规则由选择器和声明块组成:声明由属性(properties)和属性值组成. CSS介绍: 盒=框=box,边界=border,内边距 ...

  7. vim常用命令大全

    在命令状态下对当前行用== (连按=两次), 或对多行用n==(n是自然数)表示自动缩进从当前行起的下面n行.你可以试试把代码缩进任意打乱再用n==排版,相当于一般IDE里的code format.使 ...

  8. javascript之常用正则表达式

    一.校验数字的表达式 1 数字:^[0-9]*$ 2 n位的数字:^\d{n}$ 3 至少n位的数字:^\d{n,}$ 4 m-n位的数字:^\d{m,n}$ 5 零和非零开头的数字:^(0|[1-9 ...

  9. 工控图表控件ProEssentials创建3D柱状图示例代码

    使用ProEssentials可以创建3D柱状图,柱状图的形式包括线框.实体和阴影. 类似于Graph control,3D柱状图只需要YData. Subsets定义沿z轴有多少行,Points定义 ...

  10. 手机端@media screen布局自适应

    @media only screen and (min-width: 310px) and (max-width: 360px) { }@media only screen and (min-widt ...