侯捷 effective c++ 学习

[别人的笔记](https://zhuanlan.zhihu.com/p/368047311)

本笔记为简略版,本人为了复习时看这些条款标题方便而做,觉得不详细可以看链接或者百度

第一部分 让自己习惯c++

  1. 视c++为一个语言联邦
  2. 尽量以const,enum,inline替换#define:#define没有封装性,类中in-class初值设定只允许对整数常量进行(只有新编译器支持);类中可以enum{NumTurns = 5};以此替换#define;
  3. 尽可能使用const:两个成员函数如果只是const性不同,也可以被重载,const成员函数将被const对象调用;mutable使得这些成员变量即使在const成员函数内也可被修改;将常量性转除:为了避免代码重复,让non-const调用const成员函数,不过中间会用上转除:static_cast<>将非const对象转成const对象
  4. 确定对象被使用前已先被初始化:类中构造函数要直接初始化,而不是赋值,这样效率更高;用local static对象替代non-local static对象可以保证在函数使用前初始化那个对象

第二部分 构造/析构/赋值运算

  1. 了解c++默默编写并调用哪些函数
  2. 若不想使用编译器自动生成的函数,就该明确拒绝
  3. 为多态基类声明virtual析构函数:只在作为基类时才virtual,因为有vptr和vtbl占用体积;pure virtual函数:将类整成抽象类,不能有实体对象,直接virtual ~AMOV() = 0;但是之后要定义此纯虚函数
  4. 别让异常逃离析构函数:析构函数如果有异常出现往往会带来过早结束程序或发生不明确行为的风险,用双保险解决,让用户先调用close()自己解决问题,析构函数中吞下异常并记录
  5. 绝不在构造和析构过程中调用virtual函数:base class的构造过程和析构过程里其类型均被看作为base class,调用的都是当前base class版本里的virtual函数
  6. 令operator=返回一个reference to *this:只是个协议
  7. 在operator=中处理“自我赋值”:异常安全性往往自动获得自我赋值安全性,可以用精心安排的语句来获得异常安全性或者使用copy and swap技术
  8. 复制对象时勿忘其每一个成分:要复制对象的所有成员变量及所有base class部分,copy构造函数和copy assignment操作符不要互相调用,一些你觉得合理的语法可能败坏你的对象

第三部分 资源管理

  1. 以对象管理资源:这样就可依赖c++的“析构函数自动调用机制”确保资源被释放,否则会有各种想不到的情况(抛出异常)使得资源没有被释放;两个关键想法:获得资源后立刻放进管理对象内,管理对象运用析构函数确保资源被释放;auto_ptr被销毁时会自动删除它所指之物,copy构造函数或copy assignment操作符复制他们的时候,他们会变成null,复制所得的指针将会获得资源的唯一拥有权;RCSP:引用计数型智慧指针,如tr1::shared_ptrs;
  2. 在资源管理类中小心copying行为:tr1::shared_ptrs可以指定删除器
  3. 在资源管理类中提供对原始资源的访问:对RAII的.get();*;->的使用;之后有一些关于隐式转换函数的讨论
  4. 成对使用new和delete时要采取相同形式
  5. 以独立语句将newed对象置入智能指针:processWidget(std::tr1::shared_ptr(new Widget),priority())可能会泄漏资源,因为有priority(),new Widget,构造tr1::shared_ptr3个动作,可能造成new出来的指针遗失

第四部分 设计与声明

  1. 让接口容易被正确使用,不易被误用
  2. 设计class犹如设计type
  3. 宁以pass-by-reference-to-const替换pass-by-value:后者会产生对象切割(slicing)问题,可能一个继承类会被当成基类构造,而前者不会
  4. 必须返回对象时,别妄想返回其reference:例如operator*
  5. 将成员变量声明为private:否则封装性太差,客户码可能会遭受巨大改动
  6. 宁以non-member、non-friend替换member函数:封装性高,能降低编译相依度,class无法出现在多个头文件中,而namespace可以,把这些non-member、non-friend函数放在不同的头文件的同一个namespace里
  7. 若所有参数皆需类型转换,请为此采用non-member函数:基本上就是operator*要弄成friend的意思
  8. 考虑写出一个不抛异常的swap函数:可以对class template进行偏特化但不能对function template进行偏特化(解决方法:函数重载);swap函数编写流程:提供一个public swap成员函数;在class命名空间提供一个non-member,调用成员函数版本;成员版本swap绝不可抛出异常(目前不清楚原理),using std::swap能找到位于别的namespace的特化版本,std::swap不行

第五部分 实现

  1. 尽可能延后变量定义式的出现时间
  2. 尽量少做转型动作:之后再看具体的,对这方面不太了解
  3. 避免返回handles指向对象内部成分:references,指针和迭代器都是handles;成员变量的封装性最多等于返回其reference的函数的访问级别;可能导致dangling handles (空虚的号码牌)的问题,所以直接不要返回这样的handles
  4. 为“异常安全”而努力是值得的:有异常安全的函数:不泄漏任何资源,不允许数据败坏;copy and swap技术
  5. 透彻了解inlining的里里外外:隐喻方式:将函数定义于class定义式内;inline是个申请,编译器可以忽略;通常不对通过函数指针而进行的调用实施inlining;可能会造成代码膨胀;且inline函数无法随着程序库的升级而升级,在改动时所有用到inline的代码都要重新编译;不要把构造函数和析构函数整成inline
  6. 将文件的编译依存关系降到最低:相依于声明式,不要相依于定义式;程序库头文件应该以完全且仅有声明式的形式存在

第六部分 继承与面向对象设计

  1. 确定你的public继承塑模出is-a关系
  2. 避免遮掩继承而来的名称:遮掩名称,与它的类型是否相同无关;利用using声明式会使某名称的所有同名函数都被继承,而使用inline转交函数可以只继承某个特定参数形式的函数
  3. 区分接口继承和实现继承:接口继承:pure virtual函数
  4. 考虑virtual函数以外的其他选择:NVI手法等
  5. 绝不重新定义继承而来的non-virtual函数:non-virtual函数为静态绑定;不同类型指针所调用的方法会不同
  6. 绝不重新定义继承而来的缺省参数值:virtual函数系动态绑定,而缺省参数值是静态绑定
  7. 通过复合塑模出has-a或“根据某物实现出”
  8. 明智而审慎地使用private继承:继承关系为private时,编译器不会将derived class对象自动转换为base class对象;意味着根据某物实现出;能用public继承加复合实现的最好这样实现;EBO(empty base optimization空白基类最优化):用private继承一个空白类占的内存比复合小
  9. 明智而审慎地使用多重继承:virtual继承的那些对象体积大,且访问其成员变量的速度也比non-virtual base classes的速度慢;尽量不要在virtual base class里存放数据

第七部分 模板与泛型编程

  1. 了解隐式接口与编译期多态:哪一个重载函数该被调用发生在编译期;隐式接口:类型T必须支持的操作
  2. 了解typename的双重意义:在template中告诉编译器这是一个类型:typename C::const_iterator* x(嵌套从属类型名称)例外:typename不可出现在base classes list内的嵌套从属类型名称之前,也不可在member initialization list(成员初值列)中作为base class修饰符,详见p206;typedef typename
  3. 学习处理模板化基类内的名称:因为基类templates可能被特化,就会在继承类中往往拒绝在模板化基类内寻找继承而来的名称;三种方法使不进入模板化基类的行为失效:使用this->;using声明式;明白指出函数位于base class内;这三种方法的共同点:承诺模板化基类的任何特化版本都支持其一般版本提供的接口
  4. 将于参数无关的代码抽离templates
  5. 运用成员函数模板接受所有兼容类型:template class里再有template成员函数;声明泛化copy构造函数不影响编译器为其生成默认的copy构造函数,相同规则使用与copy assignment
  6. 需要类型转换时请为模板定义非成员函数:templat在实参推导过程中不将隐式类型转换函数纳入考虑,在class template内定义friend函数
  7. 请使用traits classes表现类型信息
  8. 认识template元编程:TMP模板元编程执行于编译期;将工作从运行期移至编译期,可以实现早期错误侦测和更高的执行效率

第八部分 定制new和delete

  1. 了解new-handler的行为:set_new_handler;还需要以后再看,只明白了大致意思
  2. 了解new和delete的合理替换时机:只能说有许多优点,暂时懵懂阶段
  3. 编写new和delete时需固守常规:这章纯牛马,operator new里要有无穷循环
  4. 写了placement new也要写placement delete:除了size还有别的参数

第九部分 杂项讨论

  1. 不要忽略编译器的警告
  2. 让自己熟悉包括TR1在内的标准程序库
  3. 让自己熟悉Boost
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
侯捷是一种协议栈开发工具,用于定制网络设备和应用程序。它具有更高效的C语言下载功能。 首先,侯捷采用了高度优化的算法和数据结构,以确保下载过程中的高效性。该工具的设计目标是最大化下载速度,同时最小化对系统资源的消耗。通过优化算法和数据结构的选择,侯捷可以充分利用系统的处理能力和内存资源,从而实现更快速的下载。 其次,侯捷支持多线程下载,可以同时进行多个下载任务。多线程下载使得侯捷可以同时利用多个系统资源,加快下载速度。这意味着用户可以同时下载多个文件或分割文件进行并行下载,提高了下载效率。 此外,侯捷具有智能的断点续传功能。当网络连接中断或下载被暂停时,侯捷可以自动记录已下载的部分,并在恢复连接后从中断的地方继续下载。这就避免了重新开始下载的麻烦和时间浪费,大大提高了下载的效率。 最后,侯捷提供了丰富的下载管理功能。用户可以通过侯捷进行队列管理、下载优先级设置和下载速度限制等操作,以更好地管理和控制下载任务。这样,用户可以根据自己的需求和优先级合理安排下载任务,提高整体下载效率。 综上所述,侯捷具有更高效的C语言下载功能。通过高度优化的算法和数据结构、多线程下载、断点续传和下载管理等功能,侯捷可以实现更快速、更稳定和更高效的下载体验。无论是在网络设备定制还是应用程序开发中,使用侯捷都能提高下载效率,节省时间和资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值