Rule eighteen
让接口容易被正常使用,不易被误用(Make interfaces easy to use correctly and hardto use incorrectly)
预防错误方法一:导入新类型预防错误
Data(Day day, Month month, Year year);
预防错误方法二:限制类型内什么可以做,什么不可以做
例如:以const修饰operator*, a*b = c 会报错。
准则:让types容易被正确使用,不容易被误用表现为除非友好的理由,否则应该尽量令你的types行为与内置types一致。
例如STL内所有的容器都有size()方法。
接口需要预防默写不正确的倾向。
总结:
1、好的接口容易被正确使用,不容易被复用,你应该在你的所有接口中努力达成这些性质。
2、“促进正确使用”的方法包括接口的一致性,以及与内置类型的行为兼容。
3、“组织误用”的方法包括建立新类型,限制类型上的操作,舒服对象值,已经消除客户的资源管理责任。
4、tr1::shared_ptr支持定制性删除器,这可以防止DLL问题,可以被用来自动解除互斥锁等待。
Rule nineteen
设计class犹如设计type(Treat class design as type design)
class的设计应当和语言设计者设置语言内置类型一样谨慎。
1、新的type对象如何创建和销毁
2、对象的初始化和对象的赋值该有什么差别。
3、新type对象如果被passed by value,意味着什么。
copy构造函数注意。
4、什么是新type的合法值。
5、新的type需要配合摸个继承图系么。
6、新的type需要什么样的转换。
类型转换函数。
7、什么样的操作符和函数对此type合理。
8、什么样的标准函数应该驳回。
9、谁该采用新type成员。
public private protected
10、什么是新type的未声明接口。
11、新type有多么一般化。
12、是否需要一个新type。
总结:
class的设计即使type的设计,在定义一个新type之前,请确定考虑过本条款所有讨论主题。
Rule twenty
宁以pass-by-reference- to-const 替换pass-by-value(Prefer pass-by-reference-to-const topass-by-value)
缺省情况下C++以pass value方式传递对象至函数,除非指定,调用端是以副本作为初始值,并返回返回值的副本,这些副本是由copy构造函数产出的,可能会导致费时哦操作。
以by reference 传递参数可以壁变对象切割问题
by reference 传递基类 可以传递基类或者派生类
by value 只能传递基类
对于内置函数(例如STL迭代器), by value比by reference 效率高。
总结:
1、尽量以pass-by-reference-to-const 替换pass-by-value,前者通常比较搞笑,可避免切割问题。
2、以上规则不适用于内置类型,以及STL迭代器和函数对象。 对他们而言, pass-by-value往往比较高效。
Rule twenty-two
必须返回对象时,别妄想返回reference(Dont try to return a reference when you mustreturn an object)
总结:
绝不要反悔pointer或者reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个local static对象而有可能需要多个这样的对象。
Rule twenty-three
将成员变量声明为private(Declared data members private)
为什么不用public
1、语法一致性,全变成成员函数,用户不需要考虑调用的是函数还是变量,全是函数就行。
2、精确控制,对于成员函数的访问控制更加精确。
3、封装:
a、防止在不知道的情况下被修改。
b、将变量藏在函数接口背后,实现的弹性提供。
c、封装性能够减少内容变化导致的代码破坏。
总结:
1、切记将成员变量声明为private,这可赋予客户访问数据的一致性,可惜为画风访问控制,允诺约束条件获得保证,病体哦那个class作者以充分实现弹性。
2、protected不比public更具封装性。
Rule twenty-four
宁以non-member non-friend代替member函数(Prefer non-member non-friend functions tomember functions)
non-member允许对类的相关功能有较大的弹性包裹。(?)
注意:
1、这个滚则只适用于non-member non-friend函数。
2、这个函数是class的non-member函数,也可以是其他class的member函数
比较自然的处理方法: 使用namespace
总结:
宁可那non-member non-friend代替member函数。这样能够增加封装性、包裹弹性、技能扩充性。
Rule twenty-five
若所有参数接需要类型转换,请为此采用non-member函数(Declare non-member functions when typeconversions should apply to all parameters )
只有当参数位于参数列内,这个参数才是隐式类型转换的合格参与者。
如果必须支持混合算术级数就必须
使得函数是一个non-member函数,允许编译器在每一个实参执行隐式转换。
friend函数能避免就避免
总结:
如果你需要为某个函数的所有参数(包括被this指针所指的这个隐喻参数)进行类型转换,那么这个函数必须是个non-member
Rule twenty-six(?)
考虑写出一个不抛异常的swap函数(Consider support for a non-throwing swap)
总结:
1、当std::swap的效率不高时,提供一个swap成员函数,并不抛出异常
2、如果提供一个member swap一概提供一个non member swap来调用牵着,对于class ,请特化std::swap。
3、调用swap时应针对std::Swap使用using声明式。
4、对用户定义类型进行std templates全特化是好的,但不要再std内加入某些对std全新的东西。