Effective C++读书笔记(四)
条款18: 让接口容易被正确使用,不易被误用
- “促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容
- 获得大小时全部用size而不是偶尔有length
- 如果和int类似,就要是他的行为(比如加减)和int一样
- “组织误用”的办法包括建立新类型,限制类型上的操作,舒服对象值,以及消除客户的资源管理责任
- shared_ptr支持定制型删除器,消除了”cross-DLL problem”,可用来接触互斥锁
- cross-DLL problem: 对象在DLL中被new创建,却在另一个DLL中内delete销毁
条款19: 设计class犹如设计type
设计class需要面对的问题:
- 新type的对象应该如何被创建和销毁?
- 构造函数和析构函数
- 对象的初始化和对象的赋值该有什么样的差别?
- 新对象如果被passed by value(按值传递),意味着什么?
- copy构造函数
- 什么是新type的”合法值”?
- 新type需要遵循某种继承关系吗?
- 新type需要什么样的转换?
- 什么样的操作符和函数对新type是合理的?
- 什么样的标准函数应该驳回(private)?
- 与type有关系的其他class或type?
- 什么是新type的”未声明接口”?
- 新type有多一般化?(是否应该直接定义template)
- 真的需要定义这样的一个type吗?
条款20: 宁以pass-by-reference-to-const替换pass-by-value
- 尽量以pass-by-reference-to-const替换pass-by-value。前者通常比较高效,并可避免
- 切割问题: 若传入对象是子类但传入类型是父类类型,由于调用的copy构造函数是父类的,会导致在函数内对象只含有对象的父类部分
- 具体情况具体分析,有些时候(例如STL)使用pass-by-value比较合适
条款21: 必须返回对象时,不要返回其reference
- 不要返回指针或者引用指向local stack对象或者heap-allocated对象,或返回指针或者引用指向一个local static对象而有可能同时需要多个这样的对象。
- local stack: local stack对象在函数退出之前会被销毁
- heap-allocated: 无法反之内存泄露,无法每次都delete
- local static对象: 多个对象的local static对象引用都指向同一个
条款22: 将成员变量声明为private
- 尽可能的把成员变量声明为private
- 赋予客户访问数据的一致性
- 细微划分访问控制
- 实现封装
- protected并不比public更具封装性
条款23: 宁以non-member、non-friend、替换member函数
- 提高封装性:不增加能够访问class内之private成分的函数数量
- 提高包裹弹性(packaging flexibility): 可以使该non-member函数位于一个namespace内(namespace可跨越多个源码文件),符合C++标准程序库的组织方式
- 机能扩展性: 由于此类便利函数放在多个头文件但属于同一namespace,客户可以扩展这一组函数
条款24: 若所有参数皆需类型转换,应为此采用non-member函数
例子:class有理数和int类型数相乘,即使定义了member operator函数,却不能满足交换律。使用non-member函数或许是个更好的选择
条款25: 考虑写出一个不抛异常的swap函数
(以后补充)