《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而言全新的东西。
《Effective C++》设计与声明章节的更多相关文章
- Effective C++ ——设计与声明
条款18:让接口更容易的被使用,不易误用 接口设计主要是给应用接口的人使用的,他们可能不是接口的设计者,这样作为接口的设计者就要对接口的定义更加易懂,让使用者不宜发生误用,例如对于一个时间类: cla ...
- Effective C++ —— 设计与声明(四)
条款18 : 让接口容易被正确使用,不易被误用 欲开发一个“容易被正确使用,不容易被误用”的接口,首先必须考虑客户可能做出什么样的错误操作. 1. 明智而审慎地导入新类型对预防“接口被误用”有神奇疗 ...
- 《Effective C++》第4章 设计与声明(2)-读书笔记
章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...
- 《Effective C++》第4章 设计与声明(1)-读书笔记
章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...
- 《Effective C++》阅读总结(四): 设计、声明与实现
第四章: 设计与声明 18. 让接口更容易被正确使用,不易被误用 将你的class的public接口设计的符合class所扮演的角色,必要时不仅对传参类型限制,还对传参的值域进一步限制. 19. 设计 ...
- EffectiveC++ 第4章 设计与声明
我根据自己的理解,对原文的精华部分进行了提炼,并在一些难以理解的地方加上了自己的"可能比较准确"的「翻译」. Chapter4 设计与声明 Designs and Declarat ...
- Effective C++笔记:设计与声明
条款18:让接口容易被正确使用,不易被误用 1,好的接口很容易被正确使用,不容易被误用.你应该在你的所有接口中努力达成这些性质. 2,“促进正使用”的办法包括接口的一致性,以及与内置类型的行为兼容. ...
- Effective C++笔记04:设计与声明
条款18:让接口easy被正确使用,不易被误用 1,好的接口非常easy被正确使用,不easy被误用.你应该在你的全部接口中努力达成这些性质. 2,"促进正使用"的办法包含接口的一 ...
- 《Effective C++》设计与声明:条款18-条款25
条款18:让接口容易被正确使用,不容易被误用 注意使用const,explicit,shared_ptr等来限制接口. 必要时可以创建一些新的类型,限制类型操作,束缚对象等. 注意保持接口的一致性,且 ...
- Effective C++笔记(四):设计与声明
参考:http://www.cnblogs.com/ronny/p/3747186.html 条款18:让接口容易被正确使用,不易被误用 1,好的接口很容易被正确使用,不容易被误用.你应该在你的所有接 ...
随机推荐
- Python学习笔记----列表、元组和字典的基础操作
文章目录 一.列表的基本操作 1.1 修改列表中的某个数据 1.2 获取某个元素的返回值(返回的是索引) 1.3 在列表中插入新的元素 1.4 删除列表中的元素 1.5 +和* 二.内置的函数和方法 ...
- 算法设计(动态规划应用实验报告)实现基于贪婪技术思想的Prim算法、Dijkstra算法
一.名称 动态规划法应用 二.目的 1.贪婪技术的基本思想: 2.学会运用贪婪技术解决实际设计应用中碰到的问题. 三.要求 1.实现基于贪婪技术思想的Prim算法: 2.实现基于贪婪技术思想的Dijk ...
- python-windows下如何将单个py文件生成exe文件
这需要pyinstaller,在cmd执行pip install pyinstaller命令 安装完成后,执行 pyinstaller -F 目录 可执行文件于是就在同个目录下的dist目录顺利生成了 ...
- 10.异步mysql
python中操作mysql连接.操作.断开都是网络IO #安装支持异步aiomysql的模块 pip3 install aiomysql async def execute(): # 网络IO操作, ...
- 微服务 Zipkin 链路追踪原理(图文详解)
一个看起来很简单的应用,可能需要数十或数百个服务来支撑,一个请求就要多次服务调用. 当请求变慢.或者不能使用时,我们是不知道是哪个后台服务引起的. 这时,我们使用 Zipkin 就能解决这个问题. 由 ...
- ES集群检查常用命令
一.集群检查常用命令 查询集群状态命令: curl -XGET "http://ip:port/_cluster/health?pretty" 查询Es全局状态: curl -XG ...
- 基于FPGA的AES加解密IP
Programmable AES Encryption/ Decryption IP 可编程AES加解密IP 可编程AES加解密IP提供了加解密算法功能,兼容美国国家标准与技术研究院(NIST)发布的 ...
- java学习之MybBaits
0x00前言 我前面使用的jdbc和jdbc的工具类集成的但是它们在少部分代码的情况下会会简单,但是以后如果项目较大jdbc的固定代码会很难维护,如果使用框架会简单很多,也标志着java学习正式进入到 ...
- 一次SpringBoot版本升级,引发的血案
前言 最近项目组升级了SpringBoot版本,由之前的2.0.4升级到最新版本2.7.5,却引出了一个大Bug. 到底是怎么回事呢? 1.案发现场 有一天,项目组的同事反馈给我说,我之前有个接口在新 ...
- CAN总线数据链路层(一)
1.通信机制 发送报文. 1.首先检测Bus状态,空闲 则发送 报文且回读 2.线与机制,若有两个节点同时发报文 报文结构: 通过ID进行仲裁(规则 ...