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而言全新的东西。

《Effective C++》设计与声明章节的更多相关文章

  1. Effective C++ ——设计与声明

    条款18:让接口更容易的被使用,不易误用 接口设计主要是给应用接口的人使用的,他们可能不是接口的设计者,这样作为接口的设计者就要对接口的定义更加易懂,让使用者不宜发生误用,例如对于一个时间类: cla ...

  2. Effective C++ —— 设计与声明(四)

    条款18 : 让接口容易被正确使用,不易被误用 欲开发一个“容易被正确使用,不容易被误用”的接口,首先必须考虑客户可能做出什么样的错误操作.  1. 明智而审慎地导入新类型对预防“接口被误用”有神奇疗 ...

  3. 《Effective C++》第4章 设计与声明(2)-读书笔记

    章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...

  4. 《Effective C++》第4章 设计与声明(1)-读书笔记

    章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...

  5. 《Effective C++》阅读总结(四): 设计、声明与实现

    第四章: 设计与声明 18. 让接口更容易被正确使用,不易被误用 将你的class的public接口设计的符合class所扮演的角色,必要时不仅对传参类型限制,还对传参的值域进一步限制. 19. 设计 ...

  6. EffectiveC++ 第4章 设计与声明

    我根据自己的理解,对原文的精华部分进行了提炼,并在一些难以理解的地方加上了自己的"可能比较准确"的「翻译」. Chapter4 设计与声明 Designs and Declarat ...

  7. Effective C++笔记:设计与声明

    条款18:让接口容易被正确使用,不易被误用 1,好的接口很容易被正确使用,不容易被误用.你应该在你的所有接口中努力达成这些性质. 2,“促进正使用”的办法包括接口的一致性,以及与内置类型的行为兼容. ...

  8. Effective C++笔记04:设计与声明

    条款18:让接口easy被正确使用,不易被误用 1,好的接口非常easy被正确使用,不easy被误用.你应该在你的全部接口中努力达成这些性质. 2,"促进正使用"的办法包含接口的一 ...

  9. 《Effective C++》设计与声明:条款18-条款25

    条款18:让接口容易被正确使用,不容易被误用 注意使用const,explicit,shared_ptr等来限制接口. 必要时可以创建一些新的类型,限制类型操作,束缚对象等. 注意保持接口的一致性,且 ...

  10. Effective C++笔记(四):设计与声明

    参考:http://www.cnblogs.com/ronny/p/3747186.html 条款18:让接口容易被正确使用,不易被误用 1,好的接口很容易被正确使用,不容易被误用.你应该在你的所有接 ...

随机推荐

  1. JUC(3)

    文章目录 1.集合类不安全 2.在高并发情况下arraylist()并不安全 3.高并发下set并不安全 3.测试map(高并发情况下出现问题) 1.集合类不安全 2.在高并发情况下arraylist ...

  2. 齐博x1会员中心菜单权限显示

    会员中心的菜单可以通过后台设置用户组权限进行显示或者是隐藏.比如商城里的菜单如下: 菜单文件是:\application\shop\member_menu.php return array( 'cms ...

  3. 齐博x1万能数据统计接口

    为何叫万能数据统计接口呢?因为可以调用全站任何数据表的数据总条数,并且可以设置查询条件http://qb.net/index.php/index/wxapp.count.html?table=memb ...

  4. jmeter中获取token和cookie

    ## 登录获取token 1.添加请求 1.1 输入接口中需要携带的参数的值 2.正则表达式提取器提取出值 3.输入token数据 "token":"(.+?)" ...

  5. Nacos基本学习

    一.注册中心 1.启动 1.下载nacos 在Nacos的GitHub页面,提供有下载链接,可以下载编译好的Nacos服务端或者源代码: GitHub主页:https://github.com/ali ...

  6. 在FreeSQL中实现「触发器」和软删除功能

    前言 最近做新项目,技术栈 AspNetCore + FreeSQL 这个ORM真的好用,文档也很完善,这里记录一下两个有关「触发器」的功能实现 修改实体时记录更新时间 模型代码 我的模型都是基于这个 ...

  7. POC、EXP、SRC概念厘清

    「POC」 POC可以看成是一段验证的代码,就像是一个证据,能够证明漏洞的真实性,能证明漏洞的存在即可.     https://zhuanlan.zhihu.com/p/26832890 「EXP」 ...

  8. 有依赖的背包问题(Acwing 10)

    1 # include<iostream> 2 # include<cstring> 3 # include<algorithm> 4 using namespac ...

  9. 23种设计模式之自定义Spring框架(五)

    7,自定义Spring框架 7.1 spring使用回顾 自定义spring框架前,先回顾一下spring框架的使用,从而分析spring的核心,并对核心功能进行模拟. 数据访问层.定义UserDao ...

  10. 前端学习 Nginx

    前端学习 nginx 本篇主要讲解 nginx 常用命令.基础概念(正向/反向代理.负载均衡.动静分离.高可用).配置文件结构,并通过简单的实验来体验反向代理和负载均衡,最后说一下 nginx 原理. ...