Effective C++ Item 34 区分接口继承与实现继承
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie
关联条款 Item 36
接口继承和实现继承不同。在 public 继承下, derived classes 总是继承 base class 的接口
class Shape{
public:
virtual void draw() const = 0;
virtual void error(const std::string &msg);
int objectID() const;
//...
};
class Rectangle: public Shape{...};
class Ellipse: public Shape{...};
1.pure virtual 函数 --> 让 derived classes 仅仅继承函数接口。
Shape::draw 的声明式仍是对详细 derived classes 设计者说。 “你必须提供一个 draw 函数,但我不干涉你怎么实现它”
2.impure virtual 函数 --> 让 derived classes 继承该函数的接口和缺省实现
Shape::error 的声明式告诉 derived classes 设计者说, “你必须支持一个 error 函数,但假设你不想自己写一个,能够使用 Shape要提供的缺省版本号”
3.non-virtual 函数 --> 让 derived classes 继承函数的接口及一份强制性实现
class 设计常犯两个错误
1.将全部函数声明为 non-virtual
Item 7:为多态基类声明 virtual 析构函数
2.将全部成员函数声明为 virtual
经验: impure virtual 函数同一时候指定函数声明和函数缺省行为,可能造成危急。
。
演示样例:
class AirPort{...};
class AirPlane{
public:
virtual void fly(const AirPort &destination);
//...
};
void AirPort::fly(const AirPort &destination){
//缺省代码。将飞机飞至指定的目的地
}
class ModelA: public AirPlane {...};
class ModelB: public AirPlane {...};
class ModelC: public AirPlane {
... // 未声明 fly 函数, 但C型飞机的飞行方式与A。B不同。
};
AirPort PDX(...);
AirPlane *pa = new ModelC;
//...
pa->fly(PDX); //调用 AirPlane::fly
解析:
这个程序试图以 ModelA, ModelB 的飞行方式来飞 ModelC
纠正:
切断“virtual 函数接口” 和 其“缺省实现” 之间的连接。将 AirPlane::fly 改为一个 pure virtual 函数,仅仅提供飞行接口,
另以独立函数 defaultFly 提供缺省实现。
class AirPlane{
public:
virtual void fly(const AirPort &destination) = 0;
//...
protected: // protected 由于client不须要在意飞机能不能飞
void defaultFly(const AirPort &destination); //Item 36
};
void AirPlane::defaultFly(const AirPlane &destination){
//缺省代码,将飞机飞至指定的目的地
}
class ModelA: public AirPlane{
public:
virtual void fly(const AirPort &destination){
defaultFly(destination);
}
//...
};
class ModelB: public AirPlane{
public:
virtual void fly(const AirPort &destination){
defaultFly(destination);
}
//...
};
class ModelC: public AirPlane{
public:
virtual void fly(const AirPort &destination);
//...
};
void ModelC::fly(const AirPort &destination){ // pure virtual 函数迫使 ModelC 必须提供自己的 fly 版本号
//...
}
纠正2:我更喜欢这个,没那么多变量名
class AirPlane{
public:
virtual void fly(const AirPort &destination) = 0;
//...
protected: // protected 由于client不须要在意飞机能不能飞
void defaultFly(const AirPort &destination); //Item 36
};
void AirPlane::fly(const AirPlane &destination){ //pure virtual 函数实现
//缺省代码。将飞机飞至指定的目的地
}
class ModelA: public AirPlane{
public:
virtual void fly(const AirPort &destination){
AirPlane::fly(destination);
}
//...
};
class ModelB: public AirPlane{
public:
virtual void fly(const AirPort &destination){
AirPlane::fly(destination);
}
//...
};
class ModelC: public AirPlane{
public:
virtual void fly(const AirPort &destination);
//...
};
void ModelC::fly(const AirPort &destination){ // pure virtual 函数迫使 ModelC 必须提供自己的 fly 版本号
//...
}
Effective C++ Item 34 区分接口继承与实现继承的更多相关文章
- 读书笔记 effective c++ Item 34 区分接口继承和实现继承
看上去最为简单的(public)继承的概念由两个单独部分组成:函数接口的继承和函数模板继承.这两种继承之间的区别同本书介绍部分讨论的函数声明和函数定义之间的区别完全对应. 1. 类函数的三种实现 作为 ...
- Effective C++ 34 区分接口继承和实现继承
public继承从根本上讲,有两部分:接口继承和实现继承.两者之前的区别很像函数声明与函数定义. 具体设计中,会呈现三种形式:derived class只继承成员函数的接口(纯虚函数):derived ...
- 读书笔记 effective c++ Item 18 使接口容易被正确使用,不容易被误用
1. 什么样的接口才是好的接口 C++中充斥着接口:函数接口,类接口,模板接口.每个接口都是客户同你的代码进行交互的一种方法.假设你正在面对的是一些“讲道理”的人员,这些客户尝试把工作做好,他们希望能 ...
- Effective C++ Item 36 绝不又一次定义继承而来的 non-virtual 函数
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:绝对不要又一次定义继承而来的 non-virtual 函数 --> Item 7 ...
- Effective C++ Item 34 Differentiate between inheritance of interface and inheritance of implementation
1. 成员函数的接口总是被继承. 如 Item32 所说, public 意味着 is-a, 所以对 base class 为真的任何事情对 derived class 也为真 2. 声明一个 pur ...
- Effective C++ Item 37 绝不又一次定义继承而来的缺省參数值
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:绝对不要又一次而来的缺省參数值.由于缺省參数值都是静态绑定,而 virtual 函数 ...
- Effective JavaScript Item 34 在prototype上保存方法
本系列作为EffectiveJavaScript的读书笔记. 不使用prototype进行JavaScript的编码是全然可行的,比如: function User(name, passwordHas ...
- Effective C++ -----条款34:区分接口继承和实现继承
接口继承和实现继承不同.在public继承之下,derived classes总是继承base class的接口. pure virtual函数只具体指定接口继承. 简朴的(非纯)impure vir ...
- Effective C++:规定34:区分接口继承和实现继承
(一个) class Shape { public: virtual void draw() const = 0; virtual void error(const string& msg); ...
随机推荐
- poj3264(Sparse-Table 算法模板)
poj3264 题意 询问区间最大值最小值之差. 分析 dp_max[i][j] 表示以 i 为起点,长度为 \(2^j\) 的区间最大值. 利用递推预处理出区间最大值最小值. code #inclu ...
- Tomcat配置和Spring MVC配置
Tomcat启动时,先找系统变量CATALINA_BASE,如果没有,则找CATALINA_HOME.然后找这个变量所指的目录下的conf文件夹,从中读取配置文件.最重要的配置文件:server.xm ...
- 【bzoj2393】【Cirno的完美算数教室】容斥原理的剪枝应用
(上不了p站我要死了,侵权度娘背锅) 在用容斥定理时,常常会用到dfs的形式,如果枚举完所有的情况可能会超时,其剪枝的优化很是重要. Description ~Cirno发现了一种baka数,这种数呢 ...
- Jackson反序列化提示:Can not deserialize instance of Task out of START_ARRAY token
解决方法: 1.没有绝对的方法,只能不断的测试和排查. 2.检查一下JSON数据和实体的字段结构是不是不一致导致的.比如JSON数据是数组,而实体字段为非数组. 参考: https://stackov ...
- matlab与C++以.mat文件方式进行数据相互流动
年前,放假回家之前,使用了C++与matlab之间的数据的互动的一个实验,感觉效果挺好.初步达到了目的,所以整理下来方便大家使用.减少大家编程学习的时间.希望对你们有用. #include " ...
- jquery 遍历取值问题
方法一:将a定义在外边 var a = new Array; var i = 0 ; $("img").each(function(){ a[i] = $(this).attr(& ...
- ubuntu14.04安装 chrome
安装谷歌浏览器,只需要三行代码: 打开终端,输入 cd /tmp 对于谷歌Chrome32位版本,使用如下链接: wget https://dl.google.com/linux/direct/goo ...
- DotNetBrowser入门教程(更新完善中)
DotNetBrowser 希望实现的目标:桌面软件可以完美运行Html5,内置支持MVC与WebSocket的微型服务器. 基于.Net 4.0开发.开发环境:VS2017,运行环境支持Window ...
- 转: Servlet 工作原理解析 from ibm
评点: 比较深入的讲了servlet容器, 作者许令波 (这个文章好像来自他自己的书中java web...) https://www.ibm.com/developerworks/cn/java/j ...
- 在html页面中直接嵌入图片数据
一般情况,通常是在html页面中应用图片的链接,如: <img src="http://baidu.com/logo.gif"> 但是,这样的前提是我们需要将图片先 ...