【Effection C++】继承与面向对象设计

条款34 区分接口继承和实现继承

1. 声明一个pure virtual函数的目的是为了让derived class只继承函数接口

这是有一点需要注意,对于一个函数pure virtual函数的抽象基类是无法实例化的,无论是通过new,还是直接声明对象,编译器都会报错。

但是,对于一个纯虚函数,我们是可以给这个纯虚函数提供相应的函数定义的,并且也可以执行成功,可以通过作用域来指定需要执行的函数。

2. 声明impure virtual函数的目的,是为了让derived class 继承该函数的接口和缺省实现

这种情况下,基类一般提供一种缺省实现,派生类根据自己的实际需求来判断是否需要覆盖基类的缺省实现。

除此之外,如果担心新的派生类因为遗忘了设计独立的实现,而错误的使用了缺省实现,可以参考pure function可以有着相应的定义,但是在调用时候必须明确指明。这种特性帮助我们设计派生类的时候,如果需要缺省实现就明确要求,否则就自己设计。

3. 声明non-virtual的目的是为了让derived class继承函数的接口及一份强制实现

用non-virtual函数的意义在于,其不变性凌驾于特异性之上。

相关代码示例

class Shape
{
public:virtual void draw() = 0;                       // 只提供接口virtual void error(const std::string& msg);    // 提供接口的同时提供一份默认的实现,派生类可以修改为自己的实现版本int objectID() const;                          // 提供接口的同时提供一份强制性的实现,派生类一般不应该修改该实现
};void Shape::draw()
{cout << "Shape::draw()" << endl;
}void Shape::error(const std::string& msg)   // 接口的默认实现
{cout << msg << endl;
}
int Shape::objectID() const                 // 接口的强制实现
{return 0;
}class Rectangle : public Shape
{virtual void draw();
};
void Rectangle::draw()
{cout << "Rectangle::draw()" << endl;
}int main()
{int id;Shape* ps1 = new Rectangle;ps1->draw();                            // 调用Rectangle::drawps1->error("Shape::error");             // 调用Shape::errorid = ps1->objectID();                   // 调用Shape::objectIDps1->Shape::draw();                     // 调用Shape::draw()return 0;
}

条款35:考虑virtual函数之外的选择

藉由Non-Virtual Interface 手法实现Template Methon模式

这里主要是由设计一个non-virtual函数来设定接口或者执行的框架,但是函数内则调用相应的虚函数来完成具体的实现,这样子,算法的框架整体上相同,但是实现却又不相同。

class GameCharacter{
public:int healthValue() const{……  //做事前工作int retVal=doHealthValue();//真正做实际工作……  //做事后工作return retVal;}……
private:virtual int doHealthValue() const //derived classes可以重新定义{……}
};

藉由Function Pointer实现Strategy模式

将virtual function 替换为“函数指针成员变量”,这是Strategy设计模式的一种分解表现形式

其他Strategy模式

使用function成员变量替换virtual函数,因而允许任何可调用物搭配一个兼容于需求的签名式。

或者将继承体系中的virtual函数替换为另一个继承体系内的virtual函数。传统的Strategy设计模式的实现手法。

【Effection C++】读书笔记 条款34~条款35相关推荐

  1. 读书笔记_Effective_C++_条款七:为多态基类声明virtual析构函数

    严格来说,多态分为编译时多态和运行时多态,编译时多态是函数的重载,而运行时多态则是迟绑定技术,即根据基类指针或引用的实际指向来决定采取何种行动,一般来说,多态特指运行时多态.下面我们来举有关C++多态 ...

  2. 读书笔记_Effective_C++_条款三十一:将文件间的编译依存关系降至最低(第二部分)...

    下面再来看书,去理解书上说的Handler classes就简单多了,我们大概过一下. 假设我们要写一个Person类,如下: 1 class Person 2 { 3 private: 4 stri ...

  3. 读书笔记_Effective_C++_条款十九:设计class犹如设计type

    这里初看到"class"和"type",感觉他们是说的是同一样东西,但仔细读了一下,两者在文中还是有区别的.class侧重于自定义的类,而type侧重于系统预定 ...

  4. 读书笔记_Effective_C++_条款二十四: 若所有参数皆需类型转换,请为此采用non-member函数...

    class A { private:int a; public:A(int x) :a(x){}A operator*(const A& x){return A(a*x.a);} };int ...

  5. INSPIRED启示录 读书笔记 - 第34章 恐惧、贪婪、欲望

    消费者购买产品大多源于情感需求 企业级消费者出于恐惧和贪婪购买产品:如果不买这款产品,竞争对手会超过我,黑客会攻破我的防火墙,客户将弃我而去:如果买了,会赚得更多,省得更多 大众消费者购买产品的原因更 ...

  6. 【Effection C++】读书笔记 条款29~条款30

    [Effective C++]读书笔记 Part5 实现 条款29:为异常安全而努力是值得的 当异常被抛出时,待哟异常安全性的函数会: 不泄漏任何资源. 不允许数据败坏. 异常安全函数提供以下三个保证 ...

  7. 【Effection C++】读书笔记 条款28:避免返回handles指向对象内部成分

    [Effective C++]读书笔记 Part5 实现 条款28:避免返回handles指向对象内部成分 避免返回handles(包括references,指针,迭代器)指向对象内部.遵守这个条款可 ...

  8. 【Effection C++】读书笔记 条款27:尽量少做转型动作

    [Effective C++]读书笔记 Part5 实现 条款27:尽量少做转型动作 C++中的类型转换语法 类型转换语法主要有三种不同的形式: (T)expression //将expression ...

  9. 【Effection C++】读书笔记 条款26:尽可能延后变量定义式的出现时间

    [Effective C++]读书笔记 Part5 实现 条款26:尽可能延后变量定义式的出现时间 非循环中的变量定义 尽量延后变量定义式的出现时间,主要包括两个方面: 直到必须使用变量的时候才对其进 ...

最新文章

  1. iOS-仿膜拜贴纸滚动(物理仿真)
  2. java spring 传大数据类型_Spring MVC前后端数据交互总结
  3. 【 C 】字符串查找基础笔记
  4. .netcore多语言解决方案
  5. python 下划线转驼峰_json字符串中key值下划线命名转换为驼峰命名
  6. (原创)Android6.0亮屏流程之Keyguard Window绘制
  7. [SQL]批量修改存储过程视图
  8. 有趣的php实例,8个必备的PHP功能实例代码
  9. CString .Format
  10. java五子棋代码详解_代码详解:Java和Valohai的深度学习之旅
  11. Kotlin基础-扩展
  12. linux删除所有python进程,linux 下python进程查看及关闭
  13. c语言中的正号运算符,C语言 运算符
  14. Oracle VM VirtualBox安装教程
  15. java毕业设计博弈论学习网站Mybatis+系统+数据库+调试部署
  16. mysql查询有什么意义_mysql分页查询有什么作用
  17. openCV视频操作(C++版本)
  18. 2019华为优招-南研所
  19. docker内debian安装php7.2 configure: error: Cannot find OpenSSL‘s <evp.h>
  20. 那些年被欺骗的感情---分布式实现限流操作(上)

热门文章

  1. (附源码)springboot优课在线教学系统 毕业设计 081251
  2. SpringBoot项目打包部署到其他电脑或者服务器上运行
  3. jenkins打包指定节点
  4. 电脑清空回收站怎么恢复回来?(已解决)
  5. 把VSO作为GitHub上JavaScript项目的免费CI服务器
  6. css设置文字溢出省略号显示
  7. 天天爱消除辅助-按键精灵手机安卓版-天天爱消除辅助Android源码-按键精灵脚本
  8. HP打印机查看耗材余量
  9. 服务器文件防泄密系统,文件防泄密系统及其工作方法
  10. Ubuntu18.04安装docker (阿里云镜像)