zoukankan      html  css  js  c++  java
  • EC读书笔记系列之10:条款16、17

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

    记住:

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

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

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

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

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

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

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

    1 class Date {
    2     public:
    3         Date( int month, int day, int year );
    4         ...
    5 };
    6 客户易犯错误:
    7 Date d( 30, 3, 1995 );  //传递参数次序错误
    8 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比原始指针大且慢,而且使用辅助动态内存。在许多应用程序中这些额外的执行成本并不显著,然而其“降低客户错误”的成效却相当显著(意指性价比很高)。

    条款19 设计class犹如设计type

    记住:

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

  • 相关阅读:
    【CentOS_7】使用tcpdump抓明文包
    【MySQL】MySQL-front等客户端连接MySQL_8.0等失败的解决办法
    【Python3.6】python打包成exe
    【BIGDATA】将普通文本文件导入ElasticSearch
    【python 3.6】类:访问属性及调用方法
    错误:The method replace(int, Fragment) in the type FragmentTransaction is not applicable for the arguments (int, MyFragment)
    Android Your content must have a ListView whose id attribute is 'android.R.id.list'错误的解决办法
    将文件放到Android模拟器的SD卡
    eclipse连接虚拟机
    Android 模拟器genymotion安装,eclipse 插件
  • 原文地址:https://www.cnblogs.com/hansonwang99/p/4938415.html
Copyright © 2011-2022 走看看