16、保证异常安全

1 void PrettyMenu::changBackground(std::istream &imgSrc)
2 {
3 lock(&mutex);
4 delete bgImage;
5 ++imageChanges;
6 bgImage = new Image(imgSrc);
7 unlock(&mutex);
8 }

上述代码中的问题,

a)如果 new Image 失败抛出异常会导致 mutex 没有释放。

b)如果 new Image 失败, bgImage 指向了一个已经被释放的内存。

c)如果 new Image 失败, imageChanges +1,这不符合逻辑。

异常安全函数提供三个保证:

a) 基本承诺:如果抛出异常,程序仍然保持在有效状态。没有任何对象或数据结构被破坏。

b)强烈保证:如果抛出异常,程序状态不变。(如果异常抛出,程序状态不改变,如果成功,完全成功,如果失败,完全失败。)

c)不抛掷保证:保证绝不抛异常,总是能完成承诺的功能。

17、inlining 的里里外外

inline 函数背后的整体观念是,将“对此函数调用”以函数本体替换之。这样做可能增加目标码的大小。在一台内存有限的机器上,过度热衷inlining, 会造成程序体积太大(对可用内存空间而言)。inline造成代码膨胀会造成额外的换页行为,降低指令高速缓存的击中率。

inline函数只是对编译器的一个申请,不是强制命令,申请可以是隐喻提出,也可以明确提出。隐喻提出是将函数定义在class定义式内。

构造函数和析构函数往往是inlining 的糟糕候选人。(往往比我们想象的做的更多。)

18、public继承 == is-a 关系

适用于base class 上的每一件事,一定也适用于derived class。因为每个derived class对象也都是一个base class。

19、避免遮掩继承而来的名称

#include <iostream>

using namespace std;

class Base
{
public:
virtual void mf1() = 0;
virtual void mf1(int){}
virtual void mf2(){}
void mf3(){}
void mf3(double){}
}; class Derived : public Base
{
public:
// using Base::mf1;
// using Base::mf3; virtual void mf1(){}
void mf3(){}
void mf4(){}
}; int main()
{
cout << "Hello World!" << endl; Derived d;
d.mf1();
d.mf1(5);
d.mf3();
d.mf3(2.5); return 0;
}

因为Derived实现了mf1(), 所以不在继承 mf1(int). 导致 d.mf1(5); 运行失败。

如果你在使用public继承,而又不继承那些重载函数,就违反了。 base 和 derived 之间的 is-a 关系。

在 Derived 中 声明 使用 using Base::mf1, using Base::mf3 可以解决上面的问题。

20、区分接口继承和实现继承

声明 pure virtual 函数目的是为了让Derived class 只继承函数接口。(pure virtual 可以提供函数定义。调用途径是调用时明确指定出class名称)

声明 impure virtual函数的目的,是让Derived class继承该函数接口和缺省实现。

non-virtual 函数具体指定接口继承以及强制性实现继承。

21、绝不重新定义继承而来的缺省参数值

virtual函数系动态绑定,而缺省参数值却是静态绑定。

#include <iostream>

using namespace std;

class Shape
{
public:
virtual void draw(int a = 0) {
cout << "a : " << a << endl;
}
}; class Rectangle : public Shape
{
public:
virtual void draw(int a = 1) {
cout << "a : " << a << endl;
}
}; class Cycle : public Shape
{
public:
virtual void draw(int a = 2) {
cout << "a : " << a << endl;
}
}; int main(void)
{
Shape *ps;
Shape *pr = new Rectangle;
Shape *pc = new Cycle; pr->draw();
pc->draw(); Rectangle rec;
rec.draw(); Cycle cyc;
cyc.draw(); return 0;
}

22、复合意味着has-a

当两个类之间不适合is-a的关系,所以public继承不适合用来塑模,可以在class A中包含 class B。

23、明智而慎重的使用private继承

私有继承,编译器不会自动的将Derived对象转为Base对象。private继承而来的所有成员,在derived中都变成private。

private继承意味着,只继承部分实现,不继承接口。

如果D以private继承B,意思是D对象根据B对象实现而得,再没有其他含义。

在has-a 和 private继承之间,尽量选择has-a,只有当涉及私有protected成员或者virtual函数牵扯进来时。

Effective C++ 笔记(二)的更多相关文章

  1. Effective C++ 笔记二 构造/析构/赋值运算

    条款05:了解C++默默编写并调用哪些函数 编译器默认声明一个default构造函数.一个copy构造函数.一个copy assignment操作符和一个析构函数.这些函数都是public且inlin ...

  2. Effective C++笔记(二):构造/析构/赋值运算

    参考:http://www.cnblogs.com/ronny/p/3740926.html 条款05:了解C++默默编写并调用哪些函数 如果自定义一个空类的话,会自动生成默认构造函数.拷贝构造函数. ...

  3. [Effective JavaScript 笔记]第3章:使用函数--个人总结

    前言 这一章把平时会用到,但不会深究的知识点,分开细化地讲解了.里面很多内容在高3等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...

  4. Effective Java笔记一 创建和销毁对象

    Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...

  5. 《CMake实践》笔记二:INSTALL/CMAKE_INSTALL_PREFIX

    <CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...

  6. jQuery源码笔记(二):定义了一些变量和函数 jQuery = function(){}

    笔记(二)也分为三部分: 一. 介绍: 注释说明:v2.0.3版本.Sizzle选择器.MIT软件许可注释中的#的信息索引.查询地址(英文版)匿名函数自执行:window参数及undefined参数意 ...

  7. Mastering Web Application Development with AngularJS 读书笔记(二)

    第一章笔记 (二) 一.scopes的层级和事件系统(the eventing system) 在层级中管理的scopes可以被用做事件总线.AngularJS 允许我们去传播已经命名的事件用一种有效 ...

  8. Python 学习笔记二

    笔记二 :print 以及基本文件操作 笔记一已取消置顶链接地址 http://www.cnblogs.com/dzzy/p/5140899.html 暑假只是快速过了一遍python ,现在起开始仔 ...

  9. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  10. webpy使用笔记(二) session/sessionid的使用

    webpy使用笔记(二) session的使用 webpy使用系列之session的使用,虽然工作中使用的是django,但是自己并不喜欢那种大而全的东西~什么都给你准备好了,自己好像一个机器人一样赶 ...

随机推荐

  1. 2022-02-23:如何搭建k8s单机环境(用k3s),并且搭建dashboard?

    2022-02-23:如何搭建k8s单机环境(用k3s),并且搭建dashboard? 答案2022-02-03: 使用场景:个人电脑.需要安装虚拟机,操作系统是centos. 个人电脑上测试,不需要 ...

  2. 2022-01-21:完美矩形。 给你一个数组 rectangles ,其中 rectangles[i] = [xi, yi, ai, bi] 表示一个坐标轴平行的矩形。这个矩形的左下顶点是 (xi,

    2022-01-21:完美矩形. 给你一个数组 rectangles ,其中 rectangles[i] = [xi, yi, ai, bi] 表示一个坐标轴平行的矩形.这个矩形的左下顶点是 (xi, ...

  3. vue全家桶进阶之路42:Vue3 SCSS、SASS、CSS

    SCSS和SASS都是CSS预处理器,它们的主要目的是简化CSS的编写,增加可维护性,并提供更丰富的功能.下面是它们与普通的CSS的区别: 语法:SCSS和SASS都具有比普通CSS更丰富的语法.其中 ...

  4. macbook苹果m1芯片训练机器学习、深度学习模型,resnet101在mnist手写数字识别上做加速,torch.device("mps")

    apple的m1芯片比以往cpu芯片在机器学习加速上听说有15倍的提升,也就是可以使用apple mac训练深度学习pytorch模型!!!惊呆了 安装apple m1芯片版本的pytorch 然后使 ...

  5. 使用a标签下载**.txt文件, 而不是直接打开

    今天有个使用a标签下载一个 .txt 文件,但是使用了不少方法,在点击下载的时候总是会直接打开被下载的文件,但是下载其他格式的文件就不会:也在网上找了不少资料 一.尝试href + download方 ...

  6. odoo开发教程十二:web controlle

    一:路由 odoo.http.route(route=None, **kw) 装饰器可以将对应方法装饰为处理对应的http请求,该方法须是Controller的子类. route -- 字符串或数组, ...

  7. Microsoft Office 2019 官方镜像下载 仅支持Win10系统

    Office 2019 专业增强版:(注:这是一个镜像文件) http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d6 ...

  8. GO通道:无缓冲通道与缓冲通道

    转载请注明出处: 1.通道定义 在多个协程之间进行通信和管理,可以使用 Go 语言提供的通道(Channel)类型.通道是一种特殊的数据结构,可以在协程之间进行传递数据,从而实现协程之间的通信和同步. ...

  9. 阿里云ASK试用心得(避坑贴)

    前言 常年BP阿里云的各种服务,今天却被阿里云给上了一课,这一套组合拳把我安排的明明白白,血亏50大洋,算是提前为各位大佬排坑了,预祝大家中秋快乐 目的 最近阿里云首页放出了免费试用的活动,本着不用白 ...

  10. FPGA加速技术在人机交互界面中的应用及优化

    目录 引言 随着人工智能.云计算.大数据等技术的发展,人机交互界面的重要性也越来越凸显.作为用户与计算机之间的桥梁,人机交互界面的性能和效率直接影响用户的体验和使用效果.为了优化人机交互界面的性能,我 ...