zoukankan      html  css  js  c++  java
  • 《Effective C++》设计与声明章节

    Item18:让接口容易被正确使用,不易被误用
    总结:
    1.好的接口很容易被正确使用,不容易被误用。你应该在你的所有接口中努力达到这些性质。
    2.“促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容。
    3.“阻止误用”的办法包括建立起新类型、限制类型上的操作,束缚对象的值,以及消除客户的资源管理责任。
    4.trl::shared_ptr支持定制型删除器(custon destructor)。这可以防范DLL问题,可以被用来自动解除互斥锁(mutexes)


    Item19:设计class犹如设计type
    如何设计一个高效的class?首先你必须了解你将面临的一些问题:
    1.新的type的对象应该如何被创建和销毁?这会影响到你的class构造函数和析构函数以及内存分配函数和释放函数(operator new,operator new[],operator delete,operator delete[]})。
    2.对象的初始化和对象的赋值该有怎么样的差别?这个答案决定了你的构造函数和赋值(assignment)操作符的行为,以及中间的差异。很重要的是别混淆了“初始化”和“赋值”,因为它们对应了不同的函数调用。
    3.新的type的对象如果被passed by value,意味着什么?记住,copy构造函数用来定义一个type的pass-by-value该如何实现。
    4.什么是新type的“合法值”?对于class的成员变量而言,通常只有某些数值集是有效的,那些数值决定了你的class必须维护的约束条件,也就决定了你的成员函数(特别是构造函数、赋值操作、和所谓的“setter函数”)必须进行的错误检查工作。
    5.你的type需要配合某个继承图系吗?如果继承自某些已经有的classes,那么该type就会受到那些classes的设计的束缚,特别是受到它们的函数是virtual或者是non-virtual的(尤其是析构函数)。
    6.你的新type需要类型转换吗
    7.什么样的操作符和函数对此type是合理的?这个问题的答案将决定你将为你的class声明什么member函数。
    8.什么样的标准函数应该禁止被使用?那些正是你要设置为private的函数。
    9.谁该取用新的type成员?这个提问将帮助你决定哪个成员是public,那个是private或者protected。它也帮助你决定哪一个class或function是friend。
    10.什么是新type的“未声明接口”?它对效率、异常安全性以及资源运用提供何种保证?在这方面提供的保证将为你的class实现代码加上约束条件。
    11.你的新type有多么一般化?或许你定义的并非是一个新的type,而是一整个type家族,那么你将需要使用template。
    12.你真的需要一个新的type吗?如果只是定义新的derived class以便为现有的class添加机能,那么说不定单纯定义一个或者多个non-member函数或者tmeplates,更加能够达到目标。
    总结:请记住,class的设计就是type的设计,在定义一个新的type之前,请确定你已经考虑过本条提议所覆盖的主题。


    Item20:宁以pass-by-reference-to-const替换pass-by-value
    以pass-by-reference方式传递参数可以避免slicing(对象切割问题)。当一个derived 对象以by-value的方式作为参数传递的时候,会被认为是一个base class对象,base class的copy构造函数会被调用,而“造成此对象的行为像个derived class 对象”的那些特化性质全都被切割掉了,仅仅剩下了一个base class对象。

    void show(father a)//以值传递
    {
    //do something...
    }
    int main()
    {
     son s;
     show(s);//如果你用子类的对象传进来的话,会被构造出一个父类对象,而子类对象的那些特性全都被“切割”掉了!!!
    }

    当然,如果你的参数是一个内置类型的话,用pass-by-value的方式往往比pass-by-reference的效率要高(引用的底层还是使用指针来实现的)。
    总结:

    • 尽量以pass-by-reference-to-const替换pass-by-value。前者通常比较高效,并且可以避免切割问题(slicing problem)。
    • 以上规则并不适合内置类型,以及STL的迭代器和函数对象。对它们而言,pass-by-value往往比较恰当。

    Item21:必须返回对象时,别妄想返回其reference
    总结:

    • 绝对不要返回一个reference或者pointer指向一个local stack对象,或者返回一个reference指向一个heap-allocated对象,或者返回pointer或reference指向一个local static对象而有可能同时需要多个这样的对象。条款4已经为“在单线程环境下合理返回reference指向一个local static对象”提供了一种解决方案。
    • -

    Item22:将成员变量声明为private
    总结:

    • 切记将成员变量声明为private。这可以赋予客户访问数据的一致性、可细微划分访问控制、允许约束条件获得保证,并提供class作者以充分的实现弹性。
    • protected并不比public更具有封装性。(如果想更详细的了解,可以参阅书本)

    Item23:宁以non-member、non-friend替换member函数
    总结:

    • 宁可拿non-member、non-friend替换member函数。这样做可以增加封装性、包裹弹性(packaging flexibility)和机能扩充性。
    • -

    Item24:若所有参数皆需参数类型转换,请为此采用non-member函数
    总结:

    • 如果你需要为某个函数的所有参数(包括被this指针所指的那个隐喻的参数)进行类型转换,那么这个函数必须是个non-member。

    Item25:考虑写一个不抛出异常的swap函数
    总结:

    • 当std::swap对你的类型效率不高的时候,提供一个swap函数,并确定这个函数不会抛出异常。
    • 如果你提供一个member swap,也应该提供一个non-member swap函数用来调用前者。对于classes(而非templates),也请特化std::swap。
    • 调用swap时应针对std::swap使用using声明式,然后调用swap并不带任何“命名空间资格修饰”。
    • 为“用户定义类型”进行std templates全特化是好的,但千万不要尝试在std内加入对std而言全新的东西。
    https://github.com/li-zheng-hao
  • 相关阅读:
    师生关系
    2019-2020-1 20191213兰毅达《信息安全专业导论》第九周学习总结
    2019-2020 20191213 《信息安全专业导论》第八周学习总结
    2019-2020学年 20191213兰毅达《信息安全导论》第七周学习总结
    2019-2020 20191213《信息安全专业导论》第五周学习总结
    2019-2020《信息安全专业导论》第四周学习总结
    2019-2020学年 20191217《信息安全专业导论》第三周学习总结
    师生关系
    2019-2020 20191213《信息安全专业导论》第二周学习总结
    《计算机概论》速读提问
  • 原文地址:https://www.cnblogs.com/lizhenghao126/p/11053754.html
Copyright © 2011-2022 走看看