Effective c++关键点(二)

条款18: 让接口容易被正确使用,不易被误用

18.1 考虑接口可能被怎样误用

18.2 自定义新类型对接口使用做限制

18.3 以函数替代对象

18.4 在类型内限制什么事可做,什么事不能

18.5 尽量使自定义类型行为与内置类型行为一致

18.6 不要寄希望于客户必须记得做某些事情

18.7 shared_ptr在销毁时会自动使用定义时指定的删除器

条款19: 设计class如设计type

19.1 新type的对象应该如何被创建和销毁?

19.2 对象的初始化和对象的赋值该有什么样的差别

19.3 新type的对象如果被passed by value(以值传递),意味着什么

19.4 什么是新type的"合法值"

19.5 新type是否需要配合某个继承体系

19.6 新type是否需要与其他type转换

19.7 新type需要哪些操作符和函数

19.8 什么样的成员函数应该私有

19.9 新type的成员的读取权限

19.10 定义一个class还是class template

19.11 什么是新type的"未声明接口"

条款20:宁以pass-by-reference-to-const 替换pass-by-value

20.1 缺省情况下C++以by value方式(一个继承自C的方式)传递对象至(或来自)函数。

20.2 以by reference方式传递参数可以避免slicing(对象切割)问题

20.3 内置类型(例如int)与STL的迭代器和函数对象 , pass by value往往比pass by reference的效率高些

条款21: 必须返回对象时,别妄想返回其reference

21.1 绝不要返回pointer或reference指向一个local stack对象

21.2 绝不要返回reference指向一个heap-allocated对象

21.3 绝不要返回pointer或reference指向一个local static对象而有可能同时需要多个这样的对象

条款22: 将成员变量声明为private

22.1 以函数形式访问成员变量实现读写控制

条款23: 宁以non-member、non-friend替换member函数

23.1 从封装性角度看,non-member、non-friend函数使class有更大的封装性

23.2 class 定义式对客户而言是不能扩展的,而命名空间namespace是可扩展的

条款24: 若所有参数皆需类型转换,请为此采用non-member函数

24.1 例:操作符重载

条款 25: 考虑写出一个不抛异常的 swap 函数

25.1 令non-member swap调用member swap

25.2 为class特化std 命名空间内的 swap函数

25.3 调用swap前,最好声明using std::swap

25.4 当从class没有member swap特化和non-member swap特化时,才调用std::swap

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

26.1 避免变量未被使用,而额外的调用构造函数和析构函数

条款27: 尽量少做转型动作

27.1 四种新式转型:

const_cast<T>( expression)

dynamic_cast<T>( expression)

reinterpret_cast<T>( expression)

static_cast<T>(expression)

27.2 dynamic_cast的许多实现版本执行速度相当慢

27.3 尽可能隔离转型动作,通常把它隐藏在某个函数内

条款28: 避免返回handles指向对象内部成分

28.1 handles包括指针,引用,迭代器

28.2 返回一个"代表对象内部数据"的handle时,会降低对象封装性

28.3 返回的handles可能悬空

条款29: 为"异常安全"而努力是值得的

29.1 以对象管理资源防止资源泄露

29.2 异常安全函数的三种保证:基本承诺,强烈保证,不抛掷保证

29.3 异常安全码必须提供三种保证之一;否则,它就不具备异常安全性。

29.4 强烈保证:copy-and-swap:修改对象数据的副本,然后在一个不抛异常的函数中将修改后的数据和原件置换

条款30: 透彻了解inlining的里里外外

30.1 inline函数的声明:明确声明,隐式声明

30.2 即使是inline函数,有时编译器也为函数生成一个outline函数本体(如:取某个inline函数的地址时)

30.3 改变inline函数时,客户端需要重新编译,而对于non-inline函数,客户端只需重新链接

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

31.1 让头文件尽可能不依赖其他文件,最坏让它与其他文件内的声明式(而非定义式)相依赖。

31.2 如果使用object references 或object pointers 可以完成任务,就不要使用object。(定义object需要用到类型的定义式)

31.3 声明一个函数用到某个class时只需要该class的声明式

31.4 为声明式和定义式提供不同的头文件。

31.5 Handle classes和Interface classes:

条款32: 确定public继承塑造出is-a关系

32.1 "public继承"意味is-a 关系

条款33: 避免隐藏继承而来的名称

33.1 使用using 声明继承而来的名称

33.2 转交函数(forwarding functions)

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

34.1 函数接口(function interfaces) 继承和函数实现(function implementations)继承。

34.2 声明一个纯虚函数时,derived classes只继承函数接口。

34.3 声明一个非纯虚函数时,derived classes继承该函数的接口和缺省实现。

34.4 声明一个非虚函数时,derived classes继承函数的接口及一份强制性实现。

条款35: 考虑virtual函数以外的其他选择

35.1 non-virtual interface(NVI)手法

35.2 由函数指针(Function Pointers)实现Strategy模式

35.3 由trl::function 完成Strategy模式

条款36: 绝不重新定义继承而来的non-virtual 函数

36.1 用于base对象的,也适用于derived对象

36.2 derived classes一定会继承non-virtual 函数的接口和实现

36.3 重新定义会隐藏base class的non-virtual函数

条款37: 绝不重新定义继承而来的缺省参数值

37.1 virtual函数是动态绑定,而函数的缺省参数值是静态绑定的,即实际对象为driver对象的base指针(或引用)调用virtual函数时,缺省参数值由base的virtual函数确定。

条款38: Model"has-a"or"is-implemented-in-terms-of"through composition.

38.1 在应用域,复含意味has-a。在实现域,复合意味is-implemented-in-terms-of。

条款39: 明智而审慎地使用private继承

39.1 private继承时,编译器不会自动将一个derived class对象转换为base class对象

39.2 private继承意味implemented-in-terms-of,不是因为B对象和D对象存在有任何观念上的关系

39.3 is-implemented-in-terms-ot关于组合和Private继承的选择:当需要protected 成员或virtual 函数时,

39.4 private继承:empty base最优化

EBO:空白基类最优化。

空白基类:没有non-static成员变量,没有virtual函数,也没有virtual base classes

条款40: 明智而审慎地使用多重继继承

40.1 虚继承与虚基类

Effective c++关键点(二),布布扣,bubuko.com

时间: 2024-12-05 22:48:45

Effective c++关键点(二)的相关文章

Effective c++关键点(一)

条款1:视C++为一个语言联邦 1.1 将C++视为一个由相关语言组成的联邦而非单一语言. 1.2 视C++由四块次语言组成: C:区块,语句,预处理器,内置数据类型,数组,指针 等等来自于C语言的特性. Object-Oriented C++:封装,继承,多态,virtual函数 等等面向对象特性. Template C++:泛型编程. STL:标准库. 条款2: 尽量以canst,enum,inline替换#define 2.1 宏定义的名称未登记在符号表,不易追踪编译错误. 2.2 宏定义

Effective Python 条目二:遵循PEP8风格规约

Python 增强建议#8,也被称为PEP8,是格式化Python代码的风格指引.只要符合语法,你可以随心所欲地写Python代码.然而,一致的风格使你的代码更加亲和与易于理解,及在一个大型社区中与其他Python程序员分享时促进协作.但是即使只有你自己一个人读你的代码,遵循这个风格规约将会使得以后修改起来更加容易. PEP8有一些列丰富的关于怎样去编写清晰干净的Python代码的细节.随着Python语言的演变,它将会持续更新.这是非常值得去阅读整个在线规约的(http://www.pytho

Oracle RAC安装过程中碰到的“坑”和关键点(二)

(1) 依赖包的安装 Linux下安装Oracle,除了系统配置参数,我觉得依赖包的安装是另一个比较琐碎的操作. 本次安装碰到了几个包的问题: (a) rpm -Uvh gcc-4*提示: 02. error: Failed dependencies: 03.    cloog-ppl >= 0.15 is needed by gcc-4.4.7-4.el6.x86_64 04.    cpp = 4.4.7-4.el6 is needed by gcc-4.4.7-4.el6.x86_64 不

迅速读懂:Effective STL (二)

如果有连续空闲的几天,其实可以找原书进行阅读,毕竟这里的是缩略的内容,和原版中的举例比起来这里的大部分内容只是对规则的总结. 但是要是说C++有什么特殊的科技,STL确实是其中之一,很多人评价STL源码写的像屎一样,又长又绕是真的,不过初衷可能是为了让大多数不去看源码人愉快的使用吧. 条款11:理解自定义分配器的正确用法 如果出于以下某种原因让你觉得你需要自己写一个allocator,比如:默认的在需求中太慢.浪费内存或造成过度的碎片, 或者你只对单线程的程序感兴趣, 或者想建立一个相当共享内存

effective c++ (二)

条款04:确定对象使用前已先被初始化 1.由于 c part of c++而且初始化可能导致运行期成本,那么就不保证发生初始化:例如arry是c part of c++的部分从而不能保证初始化,而STL的vector则可以保证初始化 2.由于规则复杂多变,故最佳处理办法就是:永远在使用对象之前将它初始化 3.由于C++规定对象成员的初始化动作发生在进入构造函数本体之前,故在构造函数中给定成员初值不是成员变量初始化,而是赋值动作.(C++类成员变量初始化发生于这些成员变量的default构造函数被

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

条款05:了解C++默默编写并调用哪些函数 编译器默认声明一个default构造函数.一个copy构造函数.一个copy assignment操作符和一个析构函数.这些函数都是public且inline. 1 class Empty { 2 public: 3 Empty() {...} 4 Empty(const Empty& rhs) {...} 5 ~Empty() {...} 6 Empty& operator=(const Empty& rhs) {...} 7 }; 如

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

参考:http://www.cnblogs.com/ronny/p/3740926.html 条款05:了解C++默默编写并调用哪些函数 如果自定义一个空类的话,会自动生成默认构造函数.拷贝构造函数.拷贝赋值函数.析构函数(再次感觉原文翻译的实在是太啰嗦了!). 当成员变量里有const对象或引用类型时,编译器会不能合成默认的拷贝赋值函数:当一个基类把它的拷贝赋值函数定义为private时,它的派生类 也不能生成默认的拷贝赋值函数,因为它无法完成基类成份的赋值. 条款06:若不想使用编译器自动生

你知道汽车租赁系统的关键点吗?

汽车租赁系统 主界面如下: 关键点一:怎样理清各个类之间的关系? 一共需要4个类:Car 类,Truck类,Vehicle类,VehicleUtil类 Car类:小汽车类  主要包括小汽车价格的计算方法 Truck类:货车类   主要包括货车费用的计算方法 Vehicle类:车辆类  描述车辆的一些基本信息 VehicleUtil类:工具类  创建汽车对象 下面附上一张类图: 关键点二:租车事件 首先要有两道验证:即 “输入出租人姓名验证” 和 “选择车辆验证”,代码如下: 1 if (Stri

再议Citrix PVS架构与机制

一.PVS是存储架构和网络计算架构 我们说Citrix PVS架构本质上是一个存储架构,是因为在Citrix PVS架构下,实现了计算和存储的分离.首先在传统的计算机上,计算资源和存储资源是同处于相同计算机内部的通过高速总线连接起来的组件,而在存储设备上,服务器本地的存储资源不在用于存储数据文件,存储数据文件的存储空间通过网络(TCP/IP or FC)传送到专门的存储控制器,由存储控制器来分配和管理这些元数据和IO,并最终将数据落地到硬盘空间存储起来.所以从原理出发,Citrix PVS就相当