Effective C++读书笔记---设计与声明

来源:互联网 发布:阿里的域名泛解析 编辑:程序博客网 时间:2024/05/17 19:16

所谓软件设计,是“令软件做出希望它做的事情”的步骤和做法,通常以颇为一般性的构想开始,最终演变成十足的细节,以允许特殊接口的开发
十八、条款18-让接口容易被正确使用,不易被误用
1.首先必须考虑客户可能做出什么样的错误
2.明智而审慎地导入新类型对预防“接口被误用”有神奇疗效
3.预防客户错误的另一个办法是,限制类型内什么事可做,什么事不可做。常见的限制是加上const
4.很少有其他性质比得上“一致性”更能导致“接口容易被正确的使用”。STL窗口的接口就十分的一致(虽然不是完美的一致),这使它们非常容易被使用
5.任何接口如果要求客户必须记得做某些事情,就是有着“不正确使用”的倾向,因为客户可能会忘记做那件事
6.“促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容
7.“阻止误用”的办法包括建立新类型、限制类型上的操作、束缚对象值、以及消除客户的资源管理责任
十九、条款19-设计class犹如设计type
1.如何设计高效的class呢?首先必须了解你面对的问题
[1]新type的对象应该如何被创建和销毁?
[2]对像的初始化和对象的赋值该有什么样的差别?
[3]新type的对象如果被passed by value(以值传递),意味着什么?
[4]什么是新type的“合法值”?
[5]你的新type需要配合某个继承图系(inheritance graph)吗?
[6]你的新type需要什么样的转换?
[7]什么样的操作符和函数对此新type而言是合理的?
[8]什么样的标准函数应该驳回?
[9]谁该取用新type的成员?
[10]什么是新type的“未声明接口”(undeclared interface)?
[11]你的新type有多么一般化?
[12]你真的需要一个新type吗?
二十、条款20-宁以pass-by-reference-to-const替换pass-by-value
1.窥视C++编译器底层,你会发现,references往往以指针实现出来,因此pass by reference通常意味真正传递的是指针
2.尽量以pass-by-reference-to-const替换pass-by-value。前者通常比较高效,并可避免切割问题(slicing problem)
3.2的规则并不适用于内置类型,以及STL的迭代器和函数对象。对它们而言,pass-by-value往往比较合适
二十一、条款21-必须返回对象时,别妄想返回其reference
1.绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个local static对象而有可能同时需要多个这样的对象。条款04已经为“在单线程环境中合理返回reference指向一个local stack对象”提供了一份设计实例
二十二、条款22-将成员变量声明为private
1.将成变量隐藏在函数接口的背后,可以为“所有可能的实现”提供弹性。例如这可使得成员变量被读或被写时轻松通知其他对象、可以验证class的约束条件以及函数的前提和事后状态、可以在多线程环境中执行同步控制等等。
2.protected成员变量就像public成员变量一样缺乏封装性,因为在这两种情况下,如果成员变量被改变,都会有不可预知的大量代码受到破坏。
二十三、条款23-宁以non-member、non-friend替换member函数
1.namespace可跨越多个源码文件,而class则不能
2.宁可拿non-member non-friend函数替换member函数。这样做可以增另封装性、包裹弹性(packaging flexibility)和机能扩充性
二十四、条款24-若所有参数皆需类型转换,请为此采用non-member函数
1.只有当参数被列于参数列(parameter list)内,这个参数才是隐式类型转换的合格参与者。地位相当于“被调用之成员函数所隶属的那个对象”--即this对象--的那个隐喻参数,绝不是隐式转换的合格参与者
2.如果你需要为某个函数的所有参数(包括被this指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个non-member
二十五、条款25-考虑写出一个不抛出异常的swap函数
1.能常我们不能够(不被允许)改变std命名空间内的任何东西,但可以(被允许)为标准templates(如swap)制造特化版本,使它专属于我们自己的classes。
2.当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常
3.如果你提供一个member swap,也请提供一个non-member swap用来调用前者。对于classes(而非templates),也请特化std::swap
4.调用swap时应针对std::swap使用using声明式,然后调用swap并且不带任何“命名空间资格修饰”
5.为“用户定义类型”进行std templates全特化是好的,但千万不要尝试在std内加入某些对std而言全新的东西

原创粉丝点击