条款26:尽可能延后变量定义式的出现时间

尽可能延后变量的定义,知道非得使用该变量的前一刻为止
方法A:

Widget W;
for (int i = ; i < n; ++i) {
W = ...
}

方法B:

for (int i = ; i < n; ++i) {
Widget W;
}

方法A:一个构造函数 + 一个析构函数 + n个赋值操作
方法B:n个构造函数 + n个析构函数

条款27:尽量少做转型
const_cast<T>(expression):唯一可以将对象的常量性移除(将 const 转 non-const)
dynamic_cast<T>(expression):除单元测试可以使用以外,其余情况禁用
reinterpret_cast<T>(expression): 指针类型的转型,较少使用
static_cast<T>(expression):显式转型,最常用,c++中禁用C语言旧式转型方法

强制函数调用使用虚函数的特定版本(规避多态执行),请使用作用域操作符:

virtual void Derived::func(int x) {
...
Base::func(x); //强制使用Base类里的函数
}

派生类虚函数调用基类版本时,必须显式使用作用域操作符

条款28:避免返回handle(reference、pointer、iterator)指向对象内部成分(注意不是函数体内的local变量)

遵守这条规则,可以增加封装性,规避潜在风险

条款29:为"异常安全"而努力是值得的
class PrettyMenu{
public:
void ChangeBackground(std::istream& imgsrc); //改变图像背景
private:
Mutex* mutex; //互斥器
Image* image; //目前的图像背景
int imageChange; //背景图像被改变的次数
}; void PrettyMenu::ChangeBackground(std::istream& imgsrc) {
lock(&mutex); //取得互斥器
delete image; //摆脱旧的背景图像
++imageChange; //改变图像更改次数
image = new Image(imgsrc); //安装新的背景图像
unlock(&mutex); //释放互斥器
}

上面函数没有异常安全性,因为异常安全性函数:
不泄漏任何资源:上述代码中当 new Image 发生异常时,互斥器就永远不会释放
不允许数据败坏:上述代码中当 new Image 发生异常时, imageChange已经被累加,其实新的背景图像并没有成功安装

任何使用动态内存的东西(例如所有STL容器)如果无法找到足够内存满足需求,通常会抛出一个 bad_alloc 异常
对于上述代码,我们使用对象来管理资源(image和mutex):

class PrettyMenu{
public:
void ChangeBackground(istream& imgsrc);
private:
std::shared_ptr<Image> bgImage;
}; void PrettyMenu::ChangeBackground(std::istream& imgsrc) {
Lock m1(&mutex);
bgImage.reset(new Image(imgsrc));
++imageChange;
}
条款30:透彻了解 inline 的里里外外

类的成员函数在类内定义时该函数默认为 inline 函数
inline 函数通常位于头文件内
一个表面看似 inline 的函数是否真的是 inline,取决你的 build environment,主要取决于编译器
inline 是个申请,编译器可以加以忽略,大部分编译器拒绝将太过复杂的函数、virtual 函数 inline
编译器通常不对"通过函数指针而进行的调用"实施 inline

可以联想 自定义比较函数comp通过函数指针传递给sort,实际上指针调用未inline,故sort比qsort快
将大多数 inline 限制在小型(小于10行)被频繁调用的函数身上(注意构造函数、析构函数、虚函数、递归函数通常不能 inline)

条款31:将文件间的编译依存关系降至最低

如果一个foo.cc文件,则最佳的头文件排序方式:(可有效减少隐藏依赖)

foo.h(即源文件对于的头文件)
C语言标准库头文件
c++语言标准库头文件
windows头文件(或者unix头文件)
MFC头文件(或者posix头文件)
第三方项目头文件(例如Google开源代码头文件、boost头文件)
本项目其他头文件

使用pimpl(pointer to implementation)手法,将接口与实现分离,以"声明的依存性" 替换 “定义的依存性”

最新文章

  1. js实现四大经典排序算法
  2. HashSet,TreeSet和LinkedHashSet的区别
  3. JavaScript 数据类型
  4. Rendering Problems:android.support.v7.internal.widget.ActionBarOverlayLayout 解决方法
  5. SQL——触发器——插入触发器——边学边项目写的。
  6. 后台输出HTML
  7. “System.Data.OracleClient.OracleConnection”已过时
  8. jquery.unobtrusive-ajax.js的扩展,做到片段式加载
  9. mysql 面向集合查询
  10. 完全跨站点跨域名单点(SSO)同步登录和注销
  11. Nlog、elasticsearch、Kibana以及logstash
  12. HBASE学习笔记--API
  13. IOS开发中各种型号的分辨率及软件图标的制作
  14. scrollview嵌套下拉控件嵌套recyclerview(不动第三方原基础自定义)
  15. awk命令基本使用方法
  16. fortran常用语句--读写带注释文档、动态数组等语法
  17. JS日期相减得到天数
  18. python中 is 和 == 的区别
  19. bzoj 1143
  20. [LeetCode] 64. Minimum Path Sum_Medium tag: Dynamic Programming

热门文章

  1. C++数据文件存储与加载(利用opencv)
  2. dinner 后台 nodemon 部署 Koa (关闭everything 安装或排除node_modules) # mysql 没开192.168.x.x 需要设置一下 #Navicat Premium,mysql 数据库版本有要求:mysql-5.7.17.msi 对??的支持
  3. C++ lvalue,prvalue,xvalue,glvalue和rvalue详解(from cppreference)
  4. shell脚本,awk 根据文件某列去重并且统计该列频次。
  5. java在线聊天项目 使用SWT快速制作登录窗口,可视化窗口Design 更换窗口默认皮肤(切换Swing自带的几种皮肤如矩形带圆角)
  6. ios 序列化
  7. 移动产品设计之ios系统的导航
  8. Xcode中的约束用法
  9. UVa-1368-DNA序列
  10. angular 列表渲染机制