条款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. Linux系统安装VM-Tools

    安装 vmware-tools的安装包有两个,一个是rpm包,一个是tar包,下面分别是用了这两种方法安装: 一.rpm包安装 1.在启动LINUX 虚拟机之后,在WMWare 的菜单栏中点击&quo ...

  2. 十分钟让你明白Objective-C的语法(和Java、C++的对比)

    很多想开发iOS,或者正在开发iOS的程序员以前都做过Java或者C++,当第一次看到Objective-C的代码时都会头 疼,Objective-C的代码在语法上和Java, C++有着很大的区别, ...

  3. CSS实现限制字数功能

    <div style="width:200px; white-space:nowrap;overflow:hidden;text-overflow:ellipsis; border:1 ...

  4. 关于Console的Main(String[] args)参数输入

    之前接触一个往Console里输入参数的项目,资深QA教我怎么run,灰常脸红. 今日无事,baidu之. Step1 写简单Console Code. class Program { static ...

  5. 在ASP.NET项目中使用CKEditor

    CKEditor是什么 CKEidtor是一个在线富文本编辑器,可以将让用户所见即所得的获得编辑在线文本,编辑器或自动将用户编辑的文字格式转换成html代码. 在ASP.NET工程中添加CKEdito ...

  6. javascript模式——Facade

    Facade模式为许多代码提供一个方便的接口,不现实代码实现的复杂性,这样,使用者只需要关心他的使用接口就可以使用. 下面来看一段Facade模式的运用,绑定事件在浏览器之间是不一样的,利用Facad ...

  7. 解决VS2010批量替换时经常由于内存较低而导致VS2010自动关闭的问题

    尊重原著作:本文转载自http://www.cnblogs.com/Sharping/p/3165527.html 情况描述 在使用VS2010 开发Web应用程序的时候,批量替换时经常卡死关闭. 一 ...

  8. 修复CefSharp浏览器组件中文输入Bug

    概述 最近在win10上开发wpf应用,需要将CefSharp中wpf版本的浏览器组件(版本号v51.0.0)嵌入到应用中,但是发现不支持中文输入,GitHub上有这个问题的描述,参照其提到的方法可以 ...

  9. Java与C++相异的地方

    继承标识:Java使用extends/implement,C++使用: super:调用父类的某些东西 instanceof:RTTI机制(A is instanceif B) final:类似于C+ ...

  10. sulime运行 java 和 php

    执行php脚本 1. 先配置好php环境变量 2. Tools -> Build System -> New Build System.... {      "cmd" ...