设为首页 加入收藏

TOP

C++ 编程技巧笔记记录(持续更新)(一)
2019-09-30 16:42:14 】 浏览:100
Tags:编程技巧 笔记 记录 持续 更新

目录

前言:C++是博大精深的语言,特性复杂得跟北京二环一样,继承乱得跟乱伦似的。

不过它仍然是我最熟悉且必须用在游戏开发上的语言,这篇文章用于挑选出一些个人觉得重要的条款/经验/技巧进行记录总结。
文章最后列出一些我看过的C++书籍/博客等,方便参考。

其实以前也写过相同的笔记博文,现在用markdown”重置“一下。

类/对象


1.多态基类的析构函数应总是public virtual,否则应为protected

当要释放多态基类指针指向的对象时,为了按正确顺序析构,必须得借助virtual从而先执行析构派生类再析构基类。
当基类没有多态性质时,可将基类析构函数声明protected,并且也无需耗费使用virtual。

2.编译器会隐式生成默认构造,复制构造,复制赋值,析构,(C++11)移动构造,(C++11)移动赋值的inline函数

当你在代码中用到以上函数时且没有声明该函数时,就会默认生成相应的函数。
特殊的,当你声明了构造函数(无论有无参数),都不会隐式生成默认构造函数。
不过隐式生成的函数比自己手写的函数(即使行为一样)效率要高,因为经过了编译器特殊优化。

(c++11)当你需要显式禁用生成以上某个函数时,可在函数声明尾部加上 = delete ,例如:

Type(const Type& t) = delete;

(c++11)当你需要显式默认生成以上某个函数时,可在函数声明尾部加上 = default ,例如:

Type(Tpye && t) = default;

3.不要在析构函数抛出异常,也尽量避免在构造函数抛出异常

析构函数若抛出异常,可能会使析构函数过早结束,从而可能导致一些资源未能正确释放。
构造函数若抛出异常,则无法调用析构函数,这可能导致异常发生前部分资源成功分配,却没能执行析构函数的正确释放行为。

模板


1. 不要偏特化模板函数,而是选择重载函数。

编译器匹配函数时优先选择非模板函数(重载函数),再选择模板函数,最后再选择偏特化模板函数。
当匹配到某个模板函数时,就不会再匹配选择其他模板函数,即使另一个模板函数旗下有更适合的偏特化函数。
所以这很可能导致编译器没有选择你想要的偏特化模板函数。

2.(C++11)不要重载转发引用的函数,否则使用其它替代方案

转发引用的函数是C++中最贪婪的函数,容易让需要隐式转换的实参匹配到不希望的转发引用函数。(例如下面)

template<class T>
  void f(T&& value);

void f(int a);

//当使用f(long类型的参数)或者f(short类型的参数),则不会匹配int版本而是匹配到转发引用的版本

替代方案:

  1. 舍弃重载。换个函数名或者改成传递const T&形参。
  2. 使用更复杂的标签分派或模板限制(不推荐)。

函数


1.(C++11)禁用某个函数时,使用 = delete而非private

原因有4个:

  • private函数仍需要写定义(即使那是空的实现),
  • 派生类潜在覆盖禁用函数名的可能性,
  • “=delete”语法比private语法更直观体现函数被禁用的特点,
  • 在编写非类函数的时候,无法提供private属性。

一般 = delete的类函数应为public,因为编译器先检测可访问性再检验禁用性

2.(C++11)lambda表达式一般是函数对象。特殊地,在无捕获时是函数指针。

编译器编译lambda表达式时实际上都会对每个表达式生成一种函数对象类型,然后构造出函数对象出来。
特殊地,lambda表达式在无任何捕获时,会被编译成函数,其表达式值为该函数指针(毕竟函数比函数对象更效率)。
因此在一些老旧的C++API只接受函数指针而不接受std::function的时候,可以使用无捕获的lamdba表达式。

3.(C++11)尽可能使用lamada表达式代替std::bind

直接举例说明,假设有如下Func函数:

void Func(int a, float b);

现在我们让Func绑定上2.0f作为参数b,转化一个void(int a)的函数对象。

std::function<void(int)> f;
float b = 2.0f;

//std::bind写法
f = std::bind(Func, std::placeholders::_1, b);
f(100);

//lambda表达式写法
f = [b](int a) {Func(a, b); };
f(100);

可以看到使用std::bind会十分不美观不直观,还得注意占位符位置顺序。
而使用lambda表达式可以让代码变得十分简洁优雅。

4.(C++11)使用lambda表达式时,避免默认捕获模式

按引用默认捕获容易造成引用空悬,而显示的引用捕获更能容易提醒我们捕获的是哪个变量的引用,从而更容易理清该引用的生命周期。
按值默认捕获容易让人

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇多态 下一篇抽象类和接口

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目