一.基本语法

在C++中,可以将虚函数声明为纯虚函数,语法格式为:

virtual 返回值类型 函数名 (函数参数) = ;

纯虚函数没有函数体,只有函数声明,在虚函数声明的结尾加上=0,表明此函数为纯虚函数。

最后的=0并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是纯虚函数”。

包含纯虚函数的类称为抽象类(Abstract Class)。之所以说它抽象,是因为它无法实例化,也就是无法创建对象。原因很明显,纯虚函数没有函数体,不是完整的函数,无法调用,也无法为其分配内存空间。

抽象类通常是作为基类,让派生类去实现纯虚函数。派生类必须实现纯虚函数才能被实例化。

二.使用方法

#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() 函数,才是一个完整的类,才可以被实例化。

抽象类主要有以下两个用途:

1.定义一个抽象基类,只完成部分功能,未完成的功能交给子类去实现。

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

关于纯虚函数的其它说明:

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

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

//顶层函数不能被声明为纯虚函数
void fun() = ; //compile error class base{
public :
//普通成员函数不能被声明为纯虚函数
void display() = ; //compile error
};

C++语言基础(13)-抽象类和纯虚函数的更多相关文章

  1. C++中的抽象类及纯虚函数的实现与否

    1.含有纯虚函数的叫抽象类 2.抽象类(一般是基类)中的纯虚函数无论函数体实现与否,都没有关系,系统会自动忽略 3.继承自抽象类的子类,必须要实现父类的纯虚函数才可以实例化对象 4.抽象类不允许实例化 ...

  2. 《挑战30天C++入门极限》类的分解,抽象类与纯虚函数的需要性

        类的分解,抽象类与纯虚函数的需要性 为了不模糊概念在这里我们就简单的阐述一下类的分解,前面的教程我们着重讲述了类的继承,继承的特点就是,派生类继承基类的特性,进行//站点:www.cndev- ...

  3. c++抽象类,纯虚函数

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

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

  5. C++ 纯虚函数与抽象类——virtual 和纯说明符 “=0”

    什么时候使用纯虚函数 某些类,在现实角度和项目角度都不需要实例化(不需要创建它的对象),这个类中定义的某些成员函数只是为了提供一个形式上的接口,准备上子类来做具体的实现.此时这个方法就可以定义为&qu ...

  6. c++虚函数,纯虚函数,抽象类,覆盖,重载,隐藏

    C++虚函数表解析(转) ——写的真不错,忍不住转了  http://blog.csdn.net/hairetz/article/details/4137000 浅谈C++多态性  http://bl ...

  7. c++,纯虚函数与抽象类

    1.纯虚函数的定义: (1)虚函数被“初始化”为0的函数.声明纯虚函数的一般形式是virtual 函数类型 函数名(参数表列) =0;(2)纯虚函数没有函数体:(3)最后面的“=0”并不表示函数返回值 ...

  8. C++虚函数virtual,纯虚函数pure virtual和Java抽象函数abstract,接口interface与抽象类abstract class的比较

    由于C++和Java都是面向对象的编程语言,它们的多态性就分别靠虚函数和抽象函数来实现. C++的虚函数可以在子类中重写,调用是根据实际的对象来判别的,而不是通过指针类型(普通函数的调用是根据当前指针 ...

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

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

随机推荐

  1. 【dfs】bzoj3563 DZY Loves Chinese

    因为我们可以通过把某一行读到末尾来获取真正的K,所以把它和假K异或之后就是之前联通的次数(异或的逆运算为其本身).最后一次的暴力一下. #include<cstdio> #include& ...

  2. python3开发进阶-Django框架的自带认证功能auth模块和User对象的基本操作

    阅读目录 auth模块 User对象 认证进阶 一.auth模块 from django.contrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其 ...

  3. (转)unity web 缓存解决方案

    unity web 缓存解决方案 官方发布 web版限制五十M缓存,根据自己的经验绕了过去,解决了缓存的问题.带工程,带源代码.由于本人的水平也有限,是用JS来解决的,如果你还是没有头绪,可以购买来试 ...

  4. Linux防止“rm -rf /”误删除

    说明:不解释了,运维应该在每台服务器都去配置这个问题以减少灾难的发生 方法: 1.safe-rm safe-rm是一个开源软件用来替代不太安全的rm,可以在/etc/safe-rm.conf中配置路径 ...

  5. hdu 1054 Strategic Game(tree dp)

    Strategic Game Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  6. 【iOS微博客户端开发】1、微博整体项目的构建

    回顾自己做过的项目,总结里面的知识点,分享自己参照WXHL的视频开发的一个模拟微博客户端的过程,为了还在IOS上找不到项目参考的朋友,这里会由一系列手把手的教程,如有不足,还希望可以抖抖小手,献上您宝 ...

  7. C#之Hello World(入门 )

    C#是一种简单.现代.面向对象和类型安全的编程语言. C#由C和C++发展而来.C#(英文发音C sharp)牢固地植根于C和C++语言族谱中,是Microsoft专门为使用.NET平台而创建的. • ...

  8. LeetCode(28)Implement strStr()

    题目 Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if nee ...

  9. 【Linux】pv vg lv, 加盘,扩容磁盘

    PV VG LV关系:一个物理盘(或一个lun)就是一个pv,有几个物理盘就有几个pv.一个或者几个硬盘可以组成一个vg,一个系统可以包括好几个vg,比如rootvg ,datavg等 PV组成VG, ...

  10. service 和 Controller 差别

    service  层能够看做是还有一个 DAO 层,仅仅是在里面封装了还有一些逻辑. 而 Controller 和 service 差别就大了.Controller 要处理请求映射, service ...