条款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. OpenCms创建站点过程图解——献给OpenCms的刚開始学习的人们

    非常多人都听说了OpenCms,知道了它的强大,索性的下载安装了,最终见到了久违OpenCms,看到了它简洁的界面,欣喜过后却不免一脸茫然,这个东西怎么用,我怎么用它来建站,从哪開始,无从下手,找资料 ...

  2. 获取oracle sql语句中绑定变量值的方法

    在诊断 sql的性能问题时,我们有时候须要获取其绑定变量的实际值,然后将此实际值带入到sql语句其中,用原来的sql构成select语句(带where条件),实际的运行一下,看一下选择性怎样. 本文就 ...

  3. ISG2015

    一天的成果. Re300 是男人就下一百层 一个64位的程序,放到IDA里的话,IDA就会分析不动,这样就把人给下着了.objdump –d re300 > output,这样拿到汇编代码,大概 ...

  4. 修改ORACLE-NLS_DATE_FORMAT时间格式的四种方式

    修改ORACLE-NLS_DATE_FORMAT时间格式的四种方式 改变ORACLE -NLS_DATE_FORMAT中时间显示格式的显示有以下方式: 1.可以在用户环境变量中指定(LINUX). 在 ...

  5. ORACLE 热备begin backup / end backup

    执行begin backup之后,oracle会把将要备份的数据文件都标记为hot-backup-in-progress,锁定所要备份的datafile header的scn,例如此时scn=100, ...

  6. gateone安装(web版本ssh)

    前言: 好久都没来写博客,最近忙啥去了呢? 一是忙于saltstack的二次开发,二是云计算的学习研究中,所以就一直没写东西,今天给大家介绍个工具. 好了,开始正文! 1.首先来说一下为什么要web ...

  7. SqlDataAdapter.Update()方法与SqlCommandBuilder(转)

    用SqlDataAdapter操纵数据集时最常用到的就是Fill()与Update()方法.Fill()填充DataSet或DataTable,而Update()就是将DataSet或DataTabl ...

  8. Jquery揭秘系列:谈谈bind,one,live,delegate,on事件及实现

    在Jquery里面,我们用的最多的就是事件绑定了,事件绑定有多个函数.例如:bind,one,live,delegate,on等等. on() jQuery事件绑定.on()简要概述及应用 看源码发现 ...

  9. JavaScript之cookie

    JavaScript通过Cookie实现简单的用户登录状态的保存.Cookie可以跨越多个网页使用,但不能跨域名使用,也不同跨浏览器使用. 1.设置cookie function SetCookie( ...

  10. 安卓开发之RecyclerView

    RecyclerView是一个非常好用的控件,它的效果和ListView很相似,甚至可以说RecyclerView的出现是来取代ListView的 RecyclerView比ListView更加灵活, ...