C++语言基础(13)-抽象类和纯虚函数
一.基本语法
在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)-抽象类和纯虚函数的更多相关文章
- C++中的抽象类及纯虚函数的实现与否
1.含有纯虚函数的叫抽象类 2.抽象类(一般是基类)中的纯虚函数无论函数体实现与否,都没有关系,系统会自动忽略 3.继承自抽象类的子类,必须要实现父类的纯虚函数才可以实例化对象 4.抽象类不允许实例化 ...
- 《挑战30天C++入门极限》类的分解,抽象类与纯虚函数的需要性
类的分解,抽象类与纯虚函数的需要性 为了不模糊概念在这里我们就简单的阐述一下类的分解,前面的教程我们着重讲述了类的继承,继承的特点就是,派生类继承基类的特性,进行//站点:www.cndev- ...
- c++抽象类,纯虚函数
- C++基础 (7) 第七天 多态的原理 纯虚函数和抽象类 依赖倒置原则
1 昨日回顾 2 多态的原理 1 要有继承 2 要有子类重写父类的虚函数 3 父类指针(或者引用)指向子类对象 (动态联编 虚函数表 3 证明vptr指针的存在 4 vptr指针在构造父类的时候是分步 ...
- C++ 纯虚函数与抽象类——virtual 和纯说明符 “=0”
什么时候使用纯虚函数 某些类,在现实角度和项目角度都不需要实例化(不需要创建它的对象),这个类中定义的某些成员函数只是为了提供一个形式上的接口,准备上子类来做具体的实现.此时这个方法就可以定义为&qu ...
- c++虚函数,纯虚函数,抽象类,覆盖,重载,隐藏
C++虚函数表解析(转) ——写的真不错,忍不住转了 http://blog.csdn.net/hairetz/article/details/4137000 浅谈C++多态性 http://bl ...
- c++,纯虚函数与抽象类
1.纯虚函数的定义: (1)虚函数被“初始化”为0的函数.声明纯虚函数的一般形式是virtual 函数类型 函数名(参数表列) =0;(2)纯虚函数没有函数体:(3)最后面的“=0”并不表示函数返回值 ...
- C++虚函数virtual,纯虚函数pure virtual和Java抽象函数abstract,接口interface与抽象类abstract class的比较
由于C++和Java都是面向对象的编程语言,它们的多态性就分别靠虚函数和抽象函数来实现. C++的虚函数可以在子类中重写,调用是根据实际的对象来判别的,而不是通过指针类型(普通函数的调用是根据当前指针 ...
- C++基础--虚函数和纯虚函数
虚函数的一种重要的应用是在子类重写父类方法上,一般都是在父类中声明的时候用关键字virtual修饰. 在C++中,一个父类的对象指针是可以指向子类的实例化对象,这个时候可以用该对象指针来访问父类的成员 ...
随机推荐
- JDK/Java里的设计模式
JDK/Java里的设计模式
- [AGC012F]Prefix Median
题目大意: 给定一个长度为$2n-1(n\le50)$的数组$a$,可以重排$a$中的元素,生成一个长度为$n$的数组$b$,其中$b_i$为$a_1\sim a_{2i-1}$的中位数.求对于给定的 ...
- 【OpenJudge9272】【DP】偶数个数字3
偶数个数字3 总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 131072kB [描述] 在所有的N位数中,有多少个数中有偶数个数字3? [输入] 一行给出数字N,N&l ...
- INLINE-BLOCK和FLOAT(二)(转)
一.一抹前言 没有爱的日子,时间如指尖细沙,不知不觉就流逝了.写“CSS float浮动的深入研究.详解及拓展(一)”和“CSS float浮动的深入研究.详解及拓展(二)”似乎就在不久前,然而相隔差 ...
- Microsoft office(1)分页符和分节符
Microsoft office下的页面布局中的分页符和分节符的区别: 分页符:标记一页的终止并开始下一页的点 分节符:插入分节符并在下一页开始新节 一般情况下,分节符在分页符外围,分节符一般是各种格 ...
- 测试网站页面网速的Python脚本
一.测试网站页面网速脚本 [root@salt ~]# cat check_url.py #!/usr/bin/python # coding: UTF-8 import StringIO,pycur ...
- JNI之——在cmd命令行下编译执行C/C++源文件
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46604269 一直用java来敲代码,java配置好jre路径之后.在cmd下编译 ...
- mssql性能优化
总结下SQL SERVER数据库性能优化相关的注意事项,在网上搜索了一下,发现很多文章,有的都列出了上百条,但是仔细看发现,有很多似是而非或者过时(可能对SQL SERVER6.5以前的版本或者ORA ...
- docker实战——构建Jekyll
构建第一个应用 要构建的第一个应用是Jekyll框架的自定义网站.我们会构建一下两个镜像. 一个镜像安装Jekyll以及其他用于构建Jekyll网站的必要的软件包. 一个镜像通过Apache来让Jek ...
- B3:状态模式 State
当一个对象内在状态改变时允许改变其行为,这个对象看起来像是改变了其类.状态模式主要解决当控制一个对象状态转换条件表达式过于复杂时的情况,把状态判断逻辑移到表示不同状态的一系列类中.如果状态判断很简单, ...