C++接口继承与实现继承的区别和选择
1.接口继承与实现继承的区别
《Effective C++》条款三十四:区分接口继承和实现继承中介绍的比较啰嗦,概括地说需要理解三点:
(1)纯虚函数只提供接口继承,但可以被实现;
(2)虚函数既提供接口继承,也提供了一份默认实现,即也提供实现继承;
(3)普通函数既提供接口继承,也提供实现继承。
这里假定讨论的成员函数都是public的。
这里回顾一下这三类函数,如下:
class BaseClass
{
public:
void virtual PureVirtualFunction() = 0; // 纯虚函数
void virtual ImpureVirtualFunction(); // 虚函数
void CommonFunciton(); // 普通函数
};
纯虚函数有一个“等于0”的声明,具体实现一般放在派生中(但基类也可以有具体实现),所在的类(称之为虚基类)是不能定义对象的,派生类中仍然也可以不实现这个纯虚函数,交由派生类的派生类实现,总之直到有一个派生类将之实现,才可以由这个派生类定义出它的对象。
虚函数必须有实现,否则会报链接错误。虚函数可以在基类和多个派生类中提供不同的版本,利用多态性质,在程序运行时动态决定执行哪一个版本的虚函数(机制是编译器生成的虚表)。virtual关键字在基类中必须显式指明,在派生类中不必指明,即使不写,也会被编译器认可为virtual函数,virtual函数存在的类可以定义实例对象。
普通函数则是将接口与实现都继承下来了,如果在派生类中重定义普通函数,将同名函数隐藏。事实上,也是极不推荐在派生类中隐藏基类的普通函数,如果真的要这样做,请一定要考虑是否该把基类的这个函数声明为虚函数或者纯虚函数。
下面看一个示例程序。
CShape是一个几何图形的基类,对于任何一个几何图形来说,绘制和设置颜色都是合理的操作,因此可以按照如下方式设计类:
class CShape{
public:
virtual void draw()=0;
virtual void setColor(const Color& color);
private:
Color m_color;
};
class CCircle:public CShape{};
class CEllipse:public CShape{};
上面几个类的申明就可以很好的展示继承的两个相互独立的部分:函数接口继承(inheritance of function interfaces)和函数实现继承(inheritance of function implementations)。
在基类CShape中,不能够为每一种不同的图形提供一个默认的draw实现,所以设置为纯虚函数,留给派生类来实现,也就说派生类只是继承了一个借口而已。圆和椭圆有着自己的绘制方式,所以各自有独自的绘制实现。
对于CShape::setColor,将其设置为普通的虚函数,提供一个默认的实现,这样圆和椭圆既可以重新定义,也可以使用基类的默认实现。使用普通的虚函数,派生类既使用了接口继承,也使用了实现继承。
2.接口继承与实现继承的选择
类设计时,接口继承与实现继承相互独立,代表着一定的设计意义,在二者之间进行选择时,我们需要考虑一个因素:对于无法提供默认版本的函数接口选择函数接口继承,对于能够提供默认版本的函数接口,选择函数实现继承。
参考文献
[1]读书笔记Effective_C++条款三十四:区分接口继承和实现继承
[2]李健.编写高质量代码:改善C++程序的150个建议[M].第一版.北京:机械工业出版社,2012.1:314-315
C++接口继承与实现继承的区别和选择的更多相关文章
- Effective C++ 34 区分接口继承和实现继承
public继承从根本上讲,有两部分:接口继承和实现继承.两者之前的区别很像函数声明与函数定义. 具体设计中,会呈现三种形式:derived class只继承成员函数的接口(纯虚函数):derived ...
- Effective C++:规定34:区分接口继承和实现继承
(一个) class Shape { public: virtual void draw() const = 0; virtual void error(const string& msg); ...
- 7 -- Spring的基本用法 -- 8... 抽象Bean与子Bean;Bean继承与Java继承的区别;容器中的工厂Bean;获得Bean本身的id;强制初始化Bean
7.8 深入理解容器中的Bean 7.8.1 抽象Bean与子Bean 把多个<bean.../>配置中相同的信息提取出来,集中成配置模版------这个配置模版并不是真正的Bean,因此 ...
- java一个类 继承HttpServlet 和实现Servlet区别
java一个类 继承HttpServlet 和实现Servlet区别 servlet 是一个接口,如果实现这个接口,那么就必须实现接口里面定义的所有方法 而HttpServlet实现了servlet接 ...
- Effective C++ -----条款34:区分接口继承和实现继承
接口继承和实现继承不同.在public继承之下,derived classes总是继承base class的接口. pure virtual函数只具体指定接口继承. 简朴的(非纯)impure vir ...
- c++ 接口继承和实现继承
所谓接口继承,就是派生类只继承函数的接口,也就是声明:而实现继承,就是派生类同时继承函数的接口和实现. 我们都很清楚C++中有几个基本的概念,虚函数.纯虚函数.非虚函数. 虚函数: 虚函数是指一个类中 ...
- JAVA与多线程开发(线程基础、继承Thread类来定义自己的线程、实现Runnable接口来解决单继承局限性、控制多线程程并发)
实现线程并发有两种方式:1)继承Thread类:2)实现Runnable接口. 线程基础 1)程序.进程.线程:并行.并发. 2)线程生命周期:创建状态(new一个线程对象).就绪状态(调用该对象的s ...
- pure virtual、impure virtual、non-virtual函数的接口继承和实现继承
1.abstract class 拥有pure virtual函数的class是abstract class. 不能创建abstract class的实体. 2.pure virtual 函数 他们必 ...
- [Java] 类和接口的初始化步骤 - 继承方面
类和接口在初始化化时,处理继承层级的方法不一样. 类继承的初始化:通过引用 static 字段,触发某个类的初始化,则声明该字段的类,以及该类的父类被初始化. 接口继承的初始化:通过引用 static ...
随机推荐
- 2018.4.23 linux系统
linux: 1.代表linux的内核 2.代表linux的操作系统:linux的内核和工具软件.应用软件..办公工具.开发工具. 它的特点: 1.它是开源软件,时当今最成功的开源软件之一.所以很多的 ...
- window搭建私有云,只要几分钟
本文介绍如何在window搭建私有云网盘. 工具/原料:一台window系统电脑或者window服务器(vps),Xampp 安装包,可道云kodexplorer安装包 第一步,xampp安装 1.官 ...
- 关于如何准备CKA考试
最近(2019年4月)通过了CKA考试,在此分享一下考试心得. CKA全称Certified Kubernetes Administrator,是一门在线考试,全程需要向考官分享摄像头和屏幕,考试费用 ...
- OSSEC 架构
OSSEC由很多部分组成,它有一个集中的管理端,用于监控.并接收来自代理.syslog.数据库或无代理设备的日志. 管理端(服务器) 管理端属于OSSEC部署中的中心部分.它存储了文件完整性检测数据库 ...
- Python更新库
查看系统里过期的python库,可以用pip命令 [root@vnode33 sim-enb-sgi]# pip list #列出所有安装的库 Package Version ------------ ...
- dubbo实际应用中的完整的pom.xml
http://blog.csdn.net/rodjohnsondoctor/article/details/39030601
- Buaaclubs项目介绍
简介 首先,它是社团资讯的集散地,任何希望了解北航社团信息或活动情况的同学都可以在这个平台上获取自己需要的信息,并且可以随时随地地参与社团互动,方便快捷地实现网上报名.在线咨询.活动参与等多种功能. ...
- 【Alpha】阶段第六次Scrum Meeting
[Alpha]阶段第六次Scrum Meeting 工作情况 团队成员 今日已完成任务 明日待完成任务 刘峻辰 增加教师接口 增加上课信息接口 赵智源 构建后端测试点测试框架 构建后测试点测试框架 肖 ...
- 每天学一点easyui①
引入js和css文件 <script type="text/javascript" src="js/jquery-easyui-1.4.3/jquery.min.j ...
- SQL SERVER安装(2008)
首先需要下载SQL SERVER2008安装程序:为省的麻烦给出网盘地址自行下载,百度网盘:密码:hslb 1.下载到你所选定文件夹中,我下载在E:\SQL SERVER中 2.选择第一个.exe文件 ...