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

记住:

★“促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容

★“阻止误用”的办法包括建立新类型限制类型上的操作束缚对象值,以及消除客户的资源管理责任(即类的设计者应先发制人)。

★tr1::shared_ptr支持定制型删除器。这可防范DLL问题,可被用来自动解除互斥锁等等。

--------------------------------------------------------------------------

C++的接口包括:function接口、class接口、template接口......

接口的理想情况:若客户企图使用某个接口而却没有获得他所预期的行为,应让这个代码通不过编译;若代码通过了编译,它的作为就该是客户所想要的。

a 通过导入新类型来预防接口被误用:

 class Date {
public:
Date( int month, int day, int year );
...
};
客户易犯错误:
Date d( , , ); //传递参数次序错误
Date d( , , ); //传递一个无效的月份或天数

可以通过导入简单的外覆类型(即建立新类型)来解决:

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(), Day(), Year() );

b 通过限制对象值来预防接口被误用:

如预先定义所有有效的Months:
class Month {
public:
static Month Jan() { return Month(); } //返回有效月份
static Month Feb() { return Month(); } //同上
...
private:
explicit Month( int m ); //阻止生成新的月份,这是月份专属数据
};
使用时:
Date d( Month::Mar(), Day(), Year() );

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*>(), 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比原始指针大且慢,而且使用辅助动态内存。在许多应用程序中这些额外的执行成本并不显著,然而其“降低客户错误”的成效却相当显著(意指性价比很高)。

条款19 设计class犹如设计type

记住:

★class的设计就是type的设计。在定义新的type之前,请确定你已经考虑过本条款覆盖的所有讨论主题

EC读书笔记系列之10:条款16、17的更多相关文章

  1. EC读书笔记系列之9:条款16、17

    条款16 成对使用new和delete时要采取相同形式 记住: ★若你在new表达式中使用[ ],必须在相应的delete中也使用[ ],反之亦然 -------------------------- ...

  2. EC读书笔记系列之8:条款13、14、15

    条款13 以对象管理资源 记住: ★为防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放 ★两个常被使用的RAII classes分别是tr1::shared_ptr和aut ...

  3. EC读书笔记系列之16:条款35、36、37、38、39、40

    条款35 考虑virtual函数以外的其他选择 记住: ★virtual函数的替代方案包括NVI手法及Strategy模式的多种形式.NVI手法自身是一个特殊形式的Template Method模式 ...

  4. EC读书笔记系列之5:条款9、条款10

    条款9 绝不在构造和析构过程中调用virtual函数 记住: ★在构造和析构期间不要调用virtual函数,∵这类调用从不下降至derived class ---------------------- ...

  5. EC读书笔记系列之1:条款1、条款2、条款3

    条款1:视C++为一个语言联邦 记住: ★C++高效编程守则视状况而变化,这取决于你使用C++的哪一部分 C: Object-oriented c++: Template c++: STL 条款2:尽 ...

  6. EC读书笔记系列之20:条款53、54、55

    条款53 不要轻忽编译器的警告 记住: ★严肃对待编译器发出的警告信息.努力在你的编译器的最高(最严苛)警告级别下争取“无任何警告”的荣誉 ★不要过度依赖编译器的报警能力,∵不同的编译器对待事情的态度 ...

  7. EC读书笔记系列之17:条款41、42、43、44、45、46

    条款41 了解隐式接口与编译器多态 记住: ★classes和templates都支持接口和多态 ★对classes而言接口是显式的(explicit),以函数签名为中心.多态则是通过virtual函 ...

  8. EC读书笔记系列之19:条款49、50、51、52

    条款49 了解new-handler的行为 记住: ★set_new_handler允许客户指定一个函数,在内存分配无法获得满足时被调用 ★Nothrow new是一个颇为局限的工具,∵其只适用于内存 ...

  9. EC读书笔记系列之18:条款47、48

    条款47 请使用traits classes表现类型信息 记住: ★Traits classes使得“类型相关信息”在编译期可用.它们以templates和“templates特化”完成实现 ★整合重 ...

随机推荐

  1. css属性pointer-events

    绝对定位元素盖住链接或添加某事件handle的元素后,那么该链接的默认行为(页面跳转)或元素事件将不会被触发.现在Firefox3.6+/Safari4+/Chrome支持一个称为pointer-ev ...

  2. jps无法获取到tomcat(java)进程

    一.问题描述: Ubuntu 10.10版本,同个JDK 1.6版本,启动tomcat后,使用jps无法获取本机Java进程. 二.jps工作原理: 1. java进程启动时,若没有指定 -Djava ...

  3. aspx后台生成json对象

    json对象应用很广,有时,我们要把一些数据转化为json对象,就需要用到以下方法了. 1.使用Newtonsoft.Json.DLL (推荐使用) 下载地址:http://files.cnblogs ...

  4. Preorder, Inorder, and Postorder非递归总结

    Preorder, Inorder, and Postorder Iteratively Summarization[1] 1.Pre Order Traverse public List<In ...

  5. Android 显示YUV编码格式

    ByteArrayOutputStream out = new ByteArrayOutputStream(); String path = "res/drawable/sample.yuv ...

  6. TensorFlow 深度学习笔记 逻辑回归 实践篇

    Practical Aspects of Learning 转载请注明作者:梦里风林 Github工程地址:https://github.com/ahangchen/GDLnotes 欢迎star,有 ...

  7. SpringDataRedis事务处理

    public Long leftPush(V value) { return this.ops.leftPush(this.getKey(), value); } public Long leftPu ...

  8. mysql中timestamp,datetime,int类型的区别与优劣

    转载请注明来自 souldak,微博: @evagle 以下内容 整合筛选自互联网: int 1. 占用4个字节 2. 建立索引之后,查询速度快 3. 条件范围搜索可以使用使用between 4. 不 ...

  9. 8 个优秀的 Linux 图形图像及色彩工具

    8 个优秀的 Linux 图形图像及色彩工具 1. 硬件色彩分析器LPROF LPROF 是一个用于创建设备兼容,如相机.扫描仪.显示器的ICC兼容型材的颜色分析器.这些配置提供跨设备的色彩一致性.他 ...

  10. 使用jpeglib库实现bmp转jpg

    一.vc编译jpeglib库 1.下载源代码 下载地址:http://www.ijg.org/.注意:一定要下载win32 版本 2.编译源代码. A.解压源代码,修改源代码中jconfig.vc为j ...