《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,好的接口很容易被正确使用,不容易被误用.你应该在你的所有接 ...
随机推荐
- 齐博x1直播神器聊天小插件
下载地址如下:https://down.php168.com/livemsg.rar 本插件由论坛网友笨熊提供 非常感谢他给大家提供那么一个非常好用的直播必备神器. 如下图所示,大家在直播的时候,这个 ...
- LcdToos设置“自动播放”和“上电自动开机”的作用
"自动播放"功能,常用于屏演示或者老化功能,使能后,按开关点亮屏,PX01会自动按"画面定制"栏中进行自动顺序播放:开启方法如下: 打开相应的点屏工程,在&qu ...
- 十七、Job与Cronjob
Job 与 Cronjob 一.Job Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束. 特殊说明: 1.spec.template 格式同 Pod 2 ...
- 5 why 分析法,一种用于归纳抽象出解决方案的好方法
最近在看了<微信背后的产品观 - 张小龙手抄版>,其中有段话如下: 用户需求是零散的,解决方案是归纳抽象的过程 那如何归纳抽象呢?是否有一定的实践方法论呢?经过一轮探讨和学习,有这些答案: ...
- 12、求Sn = a + aa + aaa + aaaa + ....其中a为一个数字,一共有n项。a和n由用户键盘输入。
/* 求Sn = a + aa + aaa + aaaa + ....其中a为一个数字,一共有n项.a和n由用户键盘输入. */ #include <stdio.h> #include & ...
- 【云原生 · Kubernetes】配置 Rancher docker 云平台
个人名片: 因为云计算成为了监控工程师 个人博客:念舒_C.ying CSDN主页️:念舒_C.ying 1.1 Rancher 概述 Rancher 是一个开源的企业级容器管理平台.通过 Ranc ...
- python基础语法/简单数据类型/常量与变量
今日内容概要 PEP-8规范/python基础语法 变量与常量定义 基本数据类型(整形int,字符串str,浮点型float,字典dict,列表list) 到此我们前期的配置已经可以满足我们正常编写代 ...
- 3 c++编程-提高篇-模版
重新系统学习c++语言,并将学习过程中的知识在这里抄录.总结.沉淀.同时希望对刷到的朋友有所帮助,一起加油哦! 生命就像一朵花,要拼尽全力绽放!死磕自个儿,身心愉悦! 系列文章列表: 1 c+ ...
- laravel ajax用法
$.ajax({ url:"index.php?r=sms/sms", type:"POST", data:{phone:mobileNum,_csrf:csr ...
- windows使用pyinstaller 打包sklearn模块出现死循环报错
前言 解决这个让我花费了很长时间, 我这里说的死循环,不是正常通过 --hidden-import能解决的问题. 因为我也查询了很多资料 但是无一例外都失败了(能通过 –hidden-import 解 ...