4.6 C++抽象基类和纯虚成员函数
参考:http://www.weixueyuan.net/view/6376.html
总结:
在C++中,可以通过抽象基类来实现公共接口
纯虚成员函数没有函数体,只有函数声明,在纯虚函数声明结尾加上“=0”表明此函数为纯虚成员函数。
包含纯虚成员函数的类即为抽象基类,之所以说它抽象,那是因为它无法实例化,也即无法用于创建对象。
纯虚成员函数可以被派生类继承,如果派生类不重新定义抽象基类中的所有(有多个则要重新定义多个)纯虚成员函数,则派生类同样会成为抽象基类,因而也不能用于创建对象。
一个纯虚成员函数就可以使类成为抽象基类,但是抽象基类中除了包含纯虚成员函数外,同样可以包含其它成员函数或成员变量。
只有类中的虚函数才能被声明为纯虚成员函数,普通成员函数和顶层函数均不能声明为纯虚成员函数。
抽象基类可以用于实现公共接口,在抽象基类中声明的纯虚成员函数,派生类如果想要能够创建对象,则必须全部重新定义这些纯虚成员函数。
--------------------------
公共接口是指一系列成员函数的集合,支持该接口的类必须以合适的方式重新定义这些成员函数,否则就无法创建对象。在C++中,可以通过抽象基类来实现公共接口。为了介绍抽象基类,我们需要先来了解一下纯虚成员函数。
纯虚成员函数的声明语法如下:
virtual 函数返回类型 函数名 (函数参数) = 0;
纯虚成员函数没有函数体,只有函数声明,在纯虚函数声明结尾加上“=0”表明此函数为纯虚成员函数。
包含纯虚成员函数的类即为抽象基类,之所以说它抽象,那是因为它无法实例化,也即无法用于创建对象。
例1:
#include<iostream>
using namespace std; class base
{
public :
virtual void display() = 0;
//......
}; int main()
{
base b; //compile error
return 0;
}
如本例所示,本例中只定义了一个base类,该类中声明了一个纯虚成员函数,包含纯虚成员函数的类即为抽象基类,因此base类为抽象基类。抽象基类是无法用于创建对象的,而主函数中我们尝试创建base类的对象,这是不允许的,编译提示语法错误。
纯虚成员函数可以被派生类继承,如果派生类不重新定义抽象基类中的所有(有多个则要重新定义多个)纯虚成员函数,则派生类同样会成为抽象基类,因而也不能用于创建对象。
例2:
#include<iostream>
using namespace std; class base
{
public :
base(){x = 0;}
base(int a){x = a;}
virtual void display() = 0;
int getx(){return x;}
private:
int x;
}; class derived1 : public base
{
public:
derived1(int a){ y = a;}
private:
int y;
}; class derived2 : public base
{
public:
derived2(int a, int b):base(a){ z = b;}
void display()
{
cout<<getx()<<" "<<z<<endl;
}
private:
int z;
} int main()
{
base b; //compile error
derived1 d1(5); //compile error
derived2 d2(5,6);
d2.display();
return 0;
}
在本例中定义了三个类,一个base类,base类中有一个整型成员变量x,成员函数有两个构造函数、一个getx普通成员函数和一个纯虚成员函数display。之后定义了一个derived1类,该类继承base类,在该类中新增一个整型的成员变量y,并且定义了一个构造函数。之后又定义了一个derived2类,这个类同样也新增了一个整型的成员变量z,定义了一个带参的构造函数,并显式调用了基类中的构造函数,除此之外derived2类还重新定义了基类中的纯虚成员函数display,派生类中的display函数与基类中的纯虚成员函数构成函数覆盖。我们再来看一下主函数中的情况,主函数中首先尝试创建base类的对象,因为base类包含一个纯虚成员函数,因此是抽象基类,不能创建对象。之后又尝试创建derived1的对象,derived1类继承了基类base中的纯虚成员函数,并且没有重新定义该函数,因此derived1类虽然是base类的派生类,但它仍然是抽象基类,因此同样不能创建对象。之后尝试创建derived2类的对象,该类同样是base类的派生类,同样从base类中继承了纯虚成员函数display,但是该类中同时也重新定义了该函数,因此覆盖了基类的纯虚成员函数,该类不是抽象基类,因此可以创建对象。创建derived2类的对象时调用了类中的带参构造函数,之后通过对象调用display函数,打印出成员变量x和y的值。
一个纯虚成员函数就可以使类成为抽象基类,但是抽象基类中除了包含纯虚成员函数外,同样可以包含其它成员函数或成员变量。如例2中所示的base类,类中除了包含纯虚成员函数之外,还包含了一个private成员变量x和两个构造函数及一个普通成员函数getx。
只有类中的虚函数才能被声明为纯虚成员函数,普通成员函数和顶层函数均不能声明为纯虚成员函数。如例3中企图将顶层函数和普通的成员函数声明为纯虚成员函数,这都是不允许的。
例3:
void fun() = 0; //compile error class base
{
public :
void display() = 0; //compile error
//......
};
抽象基类可以用于实现公共接口,在抽象基类中声明的纯虚成员函数,派生类如果想要能够创建对象,则必须全部重新定义这些纯虚成员函数。
4.6 C++抽象基类和纯虚成员函数的更多相关文章
- C++:抽象基类和纯虚函数的理解
转载地址:http://blog.csdn.net/acs713/article/details/7352440 抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层. ...
- (转)(C++)关于抽象基类和纯虚函数
★抽象类:一个类可以抽象出不同的对象来表达一个抽象的概念和通用的接口,这个类不能实例化(创造)对象. ★纯虚函数(pure virtual):在本类里不能有实现(描述功能),实现需要在子类中实现.例: ...
- OOP2(虚函数/抽象基类/访问控制与继承)
通常情况下,如果我们不适用某个函数,则无需为该函数提供定义.但我们必须为每个虚函数都提供定义而不管它是否被用到了,这因为连编译器也无法确定到底会适用哪个虚函数 对虚函数的调用可能在运行时才被解析: 当 ...
- C++入门经典-例8.9-抽象类,纯虚函数,创建纯虚函数
1:包含有纯虚函数的类称为抽象类,一个抽象类至少具有一个纯虚函数.抽象类只能作为基类派生出的新的子类,而不能在程序中被实例化(即不能说明抽象类的对象),但是可以使用指向抽象类的指针.在程序开发过程中并 ...
- 24 UsageEnvironment使用环境抽象基类——Live555源码阅读(三)UsageEnvironment
24 UsageEnvironment使用环境抽象基类——Live555源码阅读(三)UsageEnvironment 24 UsageEnvironment使用环境抽象基类——Live555源码阅读 ...
- 18 TaskScheduler任务调度器抽象基类——Live555源码阅读(一)任务调度相关类
这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...
- 6、面向对象以及winform的简单运用(抽象基类与接口)
抽象类与抽象方法 1.书写规范: 在类前面加上abstract关键字,就成为了抽象类:在一个方法前面加上abstract关键字,就成为了抽象方法(抽象方法不能有实现方法,直接在后面加分号) 例: ab ...
- thrift之TTransport类体系原理及源码详细解析1-类结构和抽象基类
本章主要介绍Thrift的传输层功能的实现,传输的方式多种多样,可以采用压缩.分帧等,而这些功能的实现都是相互独立,和上一章介绍的协议类实现方式比较雷同,还是先看看这部分的类关系图,如下: 由上面的类 ...
- c++之——抽象基类
在一个虚函数的声明语句的分号前加上 =0:就可以将一个虚函数变成纯虚函数,其中,=0只能出现在类内部的虚函数声明语句处.纯虚函数只用声明,而不用定义,其存在就是为了提供接口,含有纯虚函数的类是抽象基类 ...
随机推荐
- Learning by doing——百日“扇贝打卡” 历程&展望
Java结课了.如果说这学期学习这门课后最明显的成果,那就是写了那么多的博客吧.而如果说本学期最有里程碑的事,那就是背了100多天单词,其中还获得了徽章! 这次想说说从中学以来一直喜欢的一门课--英语 ...
- Android+Servlet+MySql+JSON实现简单的数据查询操作--C/S架构
本例简单地实现Android客户端与服务器端交互,主要是通过客户端输入内容(学号)提交到服务器端,服务器端与数据库交互去查询相应信息(姓名).根据这个做个完整的安卓登录是没问题的.本例数据库服务器都采 ...
- p1457 The Castle
原图找最大的房间及房间数很容易.然后从左下到右上找拆的位置.拆掉再bfs一次找面积. #include <iostream> #include <cstdio> #includ ...
- HDOJ-1806 ( Frequent values ) 线段树区间合并
http://acm.hdu.edu.cn/showproblem.php?pid=1806 线段树维护区间出现频率最高的出现次数.为了维护上者,需要维护线段前后缀的出现次数,当和其他线段在端点处的字 ...
- Linux中安装Mysql授权远程访问
一.直接授权 mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'youpassword' WITH GRANT OP ...
- 原生js实现放大镜
效果: 1. 鼠标放上去会有半透明遮罩.右边会有大图片局部图 2. 鼠标移动时右边的大图片也会局部移动 放大镜的关键原理: 鼠标在小图片上移动时,通过捕捉鼠标在小图片上的位置,定位大图片的相应位置 ...
- 创建springboot的聚合工程(一)
比起传统复杂的单体工程,使用Maven的多模块配置,可以帮助项目划分模块,鼓励重用,防止POM变得过于庞大,方便某个模块的构建,而不用每次都构建整个项目,并且使得针对某个模块的特殊控制更为方便.接下来 ...
- php导出csv
1.导出有很多种,他有自带包的导出,但是如果你要导出7,8千的数据的话就有点困难,我最近发现一个导出可以到出1万的数据,好像只能导出csv格式的. public function down_load( ...
- python 小练习 8
砝码问题1有一组砝码,重量互不相等,分别为m1.m2.m3……mn:它们可取的最大数量分别为x1.x2.x3……xn. 现要用这些砝码去称物体的重量,问能称出多少种不同的重量. 现在给你两个正整数列表 ...
- Beta阶段——第5篇 Scrum 冲刺博客
Beta阶段--第5篇 Scrum 冲刺博客 标签:软件工程 一.站立式会议照片 二.每个人的工作 (有work item 的ID) 昨日已完成的工作 人员 工作 林羽晴 完成了邮箱发送功能的测试,测 ...