改善C++11和C++14使用的42种具体方法(简版-上)

《Effective Modern C++》

1:理解template类型推导

  • 在template类型推导中,作为引用的参数被视为非引用,即忽略它们的引用性。
  • 当推导通用引用参数的类型时,左值参数得到特殊处理。
  • 当推导值参数的类型时,常量或volatile参数应该被当作非常量和 non-volatile。
  • 在推导template类型期间,数组或函数名的参数将被视为指针,除非它们用于初始化引用。

2:理解auto类型推导

  • auto类型推导和template类型推导一样,但是auto类型推导假定带括号的初始值列表相当于std::initializer_list,template类型推导不这么干。
  • 函数返回类型或lambda参数中的auto表示模板类型推导,而不是auto类型推导

3:理解decltype

  • decltype几乎总是在不做任何修改的情况下生成变量或表达式的类型
  • 对于除变量名以外的T类型左值表达式,decltype始终报告是T&。
  • C++14支持decltype(auto),它与auto一样,从其初始化器中推导出一种类型,但它使用decltype规则执行类推导。

4:知道如何查看推导出的类型

  • 通常可以通过IDE编辑器、编译器错误信息和boost::typeindex查看推导类型
  • 一些工具的结果可能都不准确或精确,因此C++类型推导规则的基础是必不可少的。

5:比起显式类型声明,更喜欢auto

  • auto变量必须初始化,通常不受类型不匹配的影响,这些类型不匹配可能导致可移植性或效率问题,可以简化重构过程,通常比显式指定类型的变量需要更少的类型。
  • 条款2和条款6会描述auto变量所面临的陷阱。

6:当auto推导出的类型不是想要的类型时,使用显式类型初始化的惯用语法

  • 不可见代理类型可以避免auto为初始化表达式推断出的错误类型。
  • 显式类型初始化语法可以强制auto推导出想要的类型。

7:当创建对象时要区分()和{}

  • 花括号初始化是最为广泛使用的初始化语法,可以防止类型转换变窄,也不要受c++语法解析问题的影响。
  • 构造函数的重载语法分析中,花括号初始化方法只要可能就会匹配std::initializer_list,即使其他的构造函数提供了更好的匹配参数。
  • 括号和大括号之间的选择可以产生显著差异的一个例子就是:创建一个两个参数的 std::vsctor<数值类型>。
  • 在template中对象创建时,括号和大括号之间的选择是一个挑战。

8:比起0和NULL,更应该用 nullptr

  • 比起0和NULL,更应该用 nullptr
  • 避免对整型和指针类型重载

9:与typedef相比,更喜欢别名声明

  • typedef不支持模板化,但是别名声明可以。
  • 别名模板避免使用::type后缀,并且在模板中使用typename前缀。
  • C++14为所有C++11类型特点转换提供别名模板。

10:与非作用域枚举相比,首选作用域枚举

  • c++98枚举风格现在被看作非作用域枚举。
  • 作用域枚举的枚举数仅在枚举中可见。只能通过cast转换。
  • 作用域枚举和非作用域枚举都支持基础类型规范。作用域枚举的默认基础类型是int。未作用域枚举没有默认基础类型。
  • 作用域枚举总是向前申明,只有在未作用域枚举的声明指定了基础类型时,未作用域才可以向前声明。

11:与私有的未定义函数相比,优先使用deleted函数

  • 与私有的未定义函数相比,优先使用deleted函数
  • 任何函数都可以deleted,包括非成员函数和模板实例函数

12:把重写函数声明为override

  • 把重写函数声明为override
  • 成员函数修饰词可以让它区别对待左值和右值对象。

13:与iterators相比,优先使用const_iterators

  • 与iterators相比,优先使用const_iterators
  • 大多数泛型代码中,优先使用非成员函数版本的begin,end,rbegin等等,而不是相应的成员函数

14:如果函数不抛出异常则声明尉noexcept

  • noexcept是函数接口的一部分,意味着调用者必须依赖它。
  • noexcept函数更容易优化。
  • noexcept在移动操作,交换,内存释放函数,析构函数中特别有价值。
  • 大多数函数是异常中立的,而不是noexcept。

15:只要有可能就使用constexpr

  • constexpr对象是常量的,并且在编译时候初始化。
  • constexpr函数在给定的参数是编译器已知的情况下可以生成编译器结果。
  • constexpr对象和函数比起非constexpr对象和函数,可以使用在更宽泛的上下文范围。
  • constexpr是对象或函数接口的一部分。

16:使const成员成为线程安全的

  • 除非确定不会在并发环境中使用,否则const成员一定要是线程安全的。
  • std::atomic变量比mutex性能更好,但只能用于操作单一变量或单一内存位置。

17:理解特殊成员函数的生成

  • 特殊成员函数就是编译器自动生成的:默认构造函数,析构函数,拷贝操作,移动操作。
  • 移动操作函数只有在没有显式声明移动操作,拷贝函数,析构函数时才生成。
  • 拷贝构造函数只有在没有显式声明拷贝构造函数时才会生成,而且如果声明了移动操作就会被删除。拷贝复制操作只有在没有显式声明拷贝赋值操作符才会生成,而且生了移动操作就会删除。如果显式声明了析构函数,则拷贝操作就会过时。
  • 成员函数模板永远不会阻止特殊成员函数的生成。

18:使用std::unique_ptr管理独占资源

  • std::unique_ptr小巧,快速,只能移动,用于管理独占资源
  • 默认情况先资源析构使用delete,但可以指定自定义删除器。有状态的删除器或函数指针会增加std::unique_ptr对象的大小。
  • std::unique_ptr很容易转换成std::shared_ptr

19:使用std::shared_ptr管理共享资源

  • std::shared_ptr对于随意的资源的共享生命周期管理提供方便的垃圾回收处理方法。
  • 相对于std::shared_ptr来说,std::shared_ptr对象通常大一倍,主要是控制块,原子引用计数操作导致。
  • 默认资源的析构是通过delete,但也支持自定义删除器。删除器的类型对std::shared_ptr的类型不起作用。
  • 避免从原始指针类型的变量生产std::shared_ptrs

20:使用std::weak_ptr代替可能发生悬空指针的std::shared_ptr

  • 使用std::weak_ptr代替可能会发生悬空指针的std::shared_ptr
  • 潜在地使用std::weak_ptr的情景有缓存,观察者列表,避免std::shared_ptr循环引用。

21:优先使用std::make_uniquestd::make_shared,而不是直接使用new

  • 相对于直接使用new来说,make函数消除了源代码重复,提升了异常安全,而且std::make_sharedstd::allocate_shared都会生成更小更快的代码。
  • 不适合使用make函数的情况有指定自定义的删除器,需要传递括号初始化器。
  • std::shared_ptrs来说,make函数不推荐使用的其他情况还有(1)有自定义内存管理的类(2)有内存问题的系统,非常大的对象,以及std::weak_ptrsstd::shared_ptrs的生命还要长的情况。
由于论坛缺少好用支持库且易本身C++本过低导致很多C++新特性无法使用。本次利用C++11/14的标准库以及一些C++知名库(RapidJson,Curl)编写支持库使用,以至于编程上不会太落后。 C++11/14标准库相对于微软类库而言与微软无关,可实现跨平台。且其拥有很多高级语法,其效率及稳定性毋庸置疑。如果能直接用标准库完成坚决不要重复造轮子。     此次封装了线程、线程池、哈希表(UnOrderedMap)、读写锁、互斥、定时器、计时器、Json、Curl等。其中Json封装于RapidJson,此库为C++最快的Json库,效率高于论坛其他工具几百倍。 Curl为知名Http库,很多公司及个人都是首选。     由于易语言5.6本核心库与其他本不太一样导致静态编译过程中出现一些问题,所以请大家最好不要使用5.6本。由于使用到了高C++库所以易语言自带的VC6编译器肯定不能编译, 在此本支持库使用了论坛的VS2014编译器,完美实现静态编译,如果你本身有这个编译器也请一定用本次配套的替换使用,否则会出现少库情况。     至于编译出来的程序能否支持XP,我想说这是肯定的,具体操作方法请参见压缩包里的说明。 备用地址 :链接:https://pan.baidu.com/s/1gY8Gm_kxMH1GOZiYaZeYZw   提取码:u1hs (里面包含编译器,支持库,例程) 文件较大,已包含 编辑所需的链接器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值