EC读书笔记系列之10:条款16、17
2015-11-05 09:26
344 查看
[b]条款18 让接口容易被正确使用,不易被误用[/b]
记住:
★“促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容
★“阻止误用”的办法包括建立新类型、限制类型上的操作,束缚对象值,以及消除客户的资源管理责任(即类的设计者应先发制人)。
★tr1::shared_ptr支持定制型删除器。这可防范DLL问题,可被用来自动解除互斥锁等等。
--------------------------------------------------------------------------
C++的接口包括:function接口、class接口、template接口......
接口的理想情况:若客户企图使用某个接口而却没有获得他所预期的行为,应让这个代码通不过编译;若代码通过了编译,它的作为就该是客户所想要的。
a 通过导入新类型来预防接口被误用:
可以通过导入简单的外覆类型(即建立新类型)来解决:
b 通过限制对象值来预防接口被误用:
c 通过限制类型上的操作来预防接口被误用:
如:常见的限制是加上const。
d 消除客户的资源管理责任(即类的设计者应先发制人):
对于如下语句:
Investment* createInvestment(); //此函数返回的是dumb ptrs
客户可将其返回值置入智能指针,因而将delete责任推给智能指针,但万一客户忘记就完了,此时应先发制人,就令上面函数返回一个智能指针:
shared_ptr有个好的性质是:它会自动使用它的“每个指针专属的删除器”,因而消除另一个潜在的客户错误:cross-DLL problem。这个问题发生于“对象在DLL中被new创建,却在另一个DLL内被delete销毁”。在许多平台上,这一类“跨DLL之new/delete成对运用”会导致运行期错误。shared_ptr无这个问题,∵它缺省的删除器是来自“tr1::shared_ptr诞生所在的那个DLL”的delete。
shared_ptr比原始指针大且慢,而且使用辅助动态内存。在许多应用程序中这些额外的执行成本并不显著,然而其“降低客户错误”的成效却相当显著(意指性价比很高)。
[b]条款19 设计class犹如设计type[/b]
记住:
★class的设计就是type的设计。在定义新的type之前,请确定你已经考虑过本条款覆盖的所有讨论主题
记住:
★“促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容
★“阻止误用”的办法包括建立新类型、限制类型上的操作,束缚对象值,以及消除客户的资源管理责任(即类的设计者应先发制人)。
★tr1::shared_ptr支持定制型删除器。这可防范DLL问题,可被用来自动解除互斥锁等等。
--------------------------------------------------------------------------
C++的接口包括:function接口、class接口、template接口......
接口的理想情况:若客户企图使用某个接口而却没有获得他所预期的行为,应让这个代码通不过编译;若代码通过了编译,它的作为就该是客户所想要的。
a 通过导入新类型来预防接口被误用:
class Date { public: Date( int month, int day, int year ); ... }; 客户易犯错误: Date d( 30, 3, 1995 ); //传递参数次序错误 Date d( 2, 30, 1995 ); //传递一个无效的月份或天数
可以通过导入简单的外覆类型(即建立新类型)来解决:
struct Day { explicit Day( int d ):val(d) {} //结构体中也可以使用成员初始化列表, //涨姿势了!!! int val; }; struct Month { explicit Month( int m ):val(m) {} int val; }; struct Year { explicit Year( int y ):val(y) {} int val; }; Date class改为: class Date { public: Date( const Month &m, const Day &d, const Year &y ); ... }; 使用时: Date d( Month(3), Day(30), Year(1995) );
b 通过限制对象值来预防接口被误用:
如预先定义所有有效的Months: class Month { public: static Month Jan() { return Month(1); } //返回有效月份 static Month Feb() { return Month(2); } //同上 ... private: explicit Month( int m ); //阻止生成新的月份,这是月份专属数据 }; 使用时: Date d( Month::Mar(), Day(30), Year(1995) );
c 通过限制类型上的操作来预防接口被误用:
如:常见的限制是加上const。
d 消除客户的资源管理责任(即类的设计者应先发制人):
对于如下语句:
Investment* createInvestment(); //此函数返回的是dumb ptrs
客户可将其返回值置入智能指针,因而将delete责任推给智能指针,但万一客户忘记就完了,此时应先发制人,就令上面函数返回一个智能指针:
std::tr1::shared_ptr<Investment> createInvestment() { //建立一个null shared_ptr并以getRidOfInvestment为删除器 std::tr1::shared_ptr<Investment> retVal( static_cast<Investment*>(0), getRidOfInvestment ); retVal = ...; //令retVal指向正确对象 return retVal; }
shared_ptr有个好的性质是:它会自动使用它的“每个指针专属的删除器”,因而消除另一个潜在的客户错误:cross-DLL problem。这个问题发生于“对象在DLL中被new创建,却在另一个DLL内被delete销毁”。在许多平台上,这一类“跨DLL之new/delete成对运用”会导致运行期错误。shared_ptr无这个问题,∵它缺省的删除器是来自“tr1::shared_ptr诞生所在的那个DLL”的delete。
shared_ptr比原始指针大且慢,而且使用辅助动态内存。在许多应用程序中这些额外的执行成本并不显著,然而其“降低客户错误”的成效却相当显著(意指性价比很高)。
[b]条款19 设计class犹如设计type[/b]
记住:
★class的设计就是type的设计。在定义新的type之前,请确定你已经考虑过本条款覆盖的所有讨论主题
相关文章推荐
- CocoaPods详解之----制作篇
- 初识keystone
- jquery 的 ajax的dataType,服务器返回了数据,但是succes:function(data)不执行
- [转]iframe自适应宽度高度
- Android 如何判断一个应用在运行
- XMPP 实现原理介绍
- CocoaPods详解之----进阶篇
- GDB十分钟教程
- Java学习(二十):获取系统参数
- aggragate mongo
- sublime 集成 ESLint
- KNN实现京东价格抓取
- Unity3D研究院之LZMA压缩文件与解压文件
- JSP程序404错误的解决浅谈
- android简单动画
- C语言中的字符变量和字符常量
- CocoaPods详解之----使用篇
- 什么是高内聚、低耦合?
- Linux下磁盘保留空间的调整,解决df看到的空间和实际磁盘大小不一致的问题
- android MotionEvent中getX()和getRawX()的区别