Effective Modern C++
Cry .
当你的能力配得上你的野心、梦想的时候,运气自然就会来了。
展开
-
Effective Modern C++ 之 lambda表达式
lambda表达式是C++11中增添的特性。lambda表达式(可调用表达式:函数,函数指针,lambda表达式,std::bind,函数对象类)是可调用表达式的一种。lambda表达式一般可以用在为智能指针创建删除器和作为算法族的实参进行传递等等。lambda表达式可以创建闭包(lambda表达式创建的运行期的对象),闭包也是可以复制的。 auto lambda_1 = [](i...原创 2020-02-14 14:55:34 · 198 阅读 · 0 评论 -
Effective Modern C++ 之 引用折叠
前面我们介绍到,当函数模板的形参的型别为万能引用时,当传递给该函数模板的实参是个左值时,则推导出的形参的类型型别为左值引用,当传递给该函数模板的实参是个右值时,则推导出的形参的类型型别为右值引用。还有在实现完美转发时,当传递给调用者的实参是左值时,使用std::forward()被调者的形参的型别为左值引用,当传递给调用者的实参是右值时,使用std::forward()被调者的形参的型别为右值引用...原创 2020-02-12 14:52:47 · 135 阅读 · 0 评论 -
Effective Modern C++ 之 std::forward
std::forward与std::move的行为机制很类似。前面我们讲过std::move的实质是对传入的实参进行强制类型转换,最终转换为右值。从这里我们可以看出std::move实施的强制类型转换是无条件的。std::forward最长使用的场景是:函数模板以万能引用为新参,任何调用另一个函数。现在先让我们看一个简单的测试案例:void fun1(std::string& str...原创 2020-02-10 15:15:16 · 174 阅读 · 0 评论 -
Effective Modern C++ 之 std::move
移动语义可以使编译器使用移动操作来替换复制操作。移动构造函数和移动复制运算符具有控制对象移动的能力。std::move()可以实现移动语义,但是std::move()到底是怎么实现的呢?其底层原理是什么呢?首先我们先观察一下std::move()的源码:template<typename T>decltype(auto) move(T&& t)noexcep...原创 2020-02-10 11:26:57 · 175 阅读 · 0 评论 -
Effective Modern C++ 之 优先选用make_unique和make_shared
我们知道make_unique和make_shared可以创建unique_ptr和shared_ptr。make_unique和make_shared底层实现是将其形参向待创建对象的构造函数作了一次完美转发,从一个new运算符产生的裸指针出发,构造了一个unique_ptr或shared_ptr,然后返回创建的这个unique_ptr或者shared_ptr。new运算符也可以创建对象,那么ne...原创 2020-02-10 10:02:29 · 352 阅读 · 0 评论 -
Effective Modern C++ 之 shared_ptr
我们前面介绍了unique_ptr智能指针,它对它所指向的对象资源具有专属所有权。这个就直接导致unique_ptr是无法进行复制操作的。有没有一种智能指针对象资源不具有专属所有权,也就是它可以进行复制操作。当然有的。那就是shared_ptr智能指针。shared_ptr也是对裸指针进行包装的类。shared_ptr智能指针对它所指涉的对象资源具有共享所有权,也就是说指涉到该对象资源的所有的...原创 2020-02-09 11:10:43 · 125 阅读 · 0 评论 -
Effective Modern C++ 之 unique_ptr
首先我们应该知道为什么要使用智能指针。智能指针是对野指针的包装,它们的行为类似于被封装起来的裸指针。因此,避免了很多裸指针所带来的许多陷阱。直接使用裸指针可能会造成未定义行为,可能会产生悬垂指针等待。C++11中共有三种智能指针:unique_ptr,shared_ptr和weak_ptr。今天我们就先深层次了解一下unique_ptr吧。unique_ptr具有专属所有权的语义,因此它只能进...原创 2020-02-08 22:50:06 · 297 阅读 · 0 评论 -
Effective Modern C++ 之 特种成员函数
首先我们应该知道:特种成员函数是由C++编译器自动生成的函数。C++的特种成员函数包括:析构函数,默认构造函数,析构函数,复制构造函数,复制赋值运算符,移动构造函数,移动赋值运算符。 当我们使用移动构造函数和移动复制运算符时,其实质是:支持移动操作的成员上执行移动操作,不支持移动操作的成员上执行复制操作。 生成移动操作的精确条件和复制操作的精确条件是不同的。两种复制操作时批次独立的,声明了其...原创 2020-02-08 11:42:46 · 141 阅读 · 0 评论 -
Effective Modern C++ 之 constexpr
程序的执行分为编译阶段和运行阶段。为了让程序的执行时间最短,我们应该在编译阶段和运行阶段进行权衡。constexpr应用于对象时,对象具有const属性(加强版的const),其对象在编译阶段就已知。这些对象可能被存放在ROM里面(只读内存)。constexpr一般被使用在数组的尺寸规格,整型模板实参,枚举量的值和对齐规格中。 我们应该有效的区别const和constexpr。constexpr...原创 2020-02-08 10:11:52 · 105 阅读 · 0 评论 -
Effective Modern C++ noexcept
我们知道关于函数发射异常这件事,真正重要的信息是他会不会发射异常。在C++11中,无条件的为函数声明noexcept就是为了不会发射异常的函数而准备的。函数是否要加上如此声明,事关接口的设计。当我们知道函数不会发射异常但却没有为函数加上noexcept,这就是接口规格设计存在缺陷。为不会发射异常的函数加上noexcept,可以让编译器生成更好的代码(也就是说对代码会进行优化)。在带有noexc...原创 2020-02-07 11:04:30 · 139 阅读 · 0 评论 -
Effective Modern C++ 之 override
我们都知道C++是面向对象的语言,而在C++中OOP的三大特性是:数据抽象,继承和多态。在实现多态中是通过虚函数来实现的,派生类中的虚函数的实现会改写基类中对应的虚函数的实现。而要改写的这个动作的完全实现必须满足一些要求: 基类中的函数必须是虚函数。 基类和派生类中的函数的签名必须完全相等。 基类和派生类中的函数的引用饰词(可以让左值和右值的对象的处理区分开来)必须完全相...原创 2020-02-06 15:53:52 · 142 阅读 · 0 评论 -
Effective Modern C++ 之 () 和{}的区别
小括号和大括号都可以给对象进行初始化。但是大括号的范围更广,效率更高。大括号禁止内建型别之间隐式窄化型别转化,也就是对对象初始化时,不会发生隐式的型别转化。大括号还可以对最令人苦恼之解析语法免疫。当我们对对象进行默认构造时,有时也不注意,我们会写成声明一个函数,这个是很危险的。但是,使用大括号进行初始化,就不会出现此类的问题。前面我们讲过使用大括号的auto型别推导,会推导成std::in...原创 2020-02-02 11:20:07 · 234 阅读 · 0 评论 -
Effective Modern C++ 之 删除函数与private未定义的函数
如果我们想阻止对象去调用函数,我们便可以把该函数声明成private,并且不去定义它。但是这样真的可以阻止客户对象区调用它吗?其实是不行的,虽然我们把函数声明为private,客户对象只是不能直接的去进行调用,但是却可以间接的进行调用(通过使用接口函数对其进行调用便可)。有什么方法可以让一个函数永远不会使用呢? 当然有啊~~ C++11中,有更好的途径来达成效果上相同的结果:使用“=del...原创 2020-02-06 11:58:59 · 134 阅读 · 0 评论 -
Effective Modern C++ 之 枚举型别
枚举型别也是类,是一种特殊的类(里面只允许存在整型常量的类)。枚举量都是整型常量。枚举型别分为限定作用的和不限定作用域的。顾名思义,不限定作用域的表示枚举量在任何地方都可以使用,而限定作用域的只能在其作用域里使用。因此,不限定作用域的枚举类会泄漏名字,造成名字的空间污染。 限定作用域的枚举类的枚举量是更强型别的,也就是说其枚举量不发生隐式的类型转换。而不限定作用域的枚举类的枚举量却可...原创 2020-02-05 22:11:44 · 122 阅读 · 0 评论 -
Effective Modern C++ 之 优先选用nullptr,而非或NULL
我们知道C++的基本观点是0的型别是int,而非指针。0和NULL(C里面的空指针)在C++都不具备指针型别。C++中我们使用nullptr一般表示空指针(其实nullptr不具备任何的型别,它是一种任意类型的指针)。nullptr还可以提高代码的清晰性,nullptr不会造成0和NULL造成的代码的二义性问题,因此C++中表示空指针时,相对于0和NULL,我们应该优先选用nullptr。...原创 2020-02-05 10:56:29 · 112 阅读 · 0 评论 -
Effective Modern C++ 之 auto的使用
前面的总结中,我们对auto进行了总结。我们了解到auto的类型推导实质是模板类型推导。现在我们来讲解一下auto的使用,有人会觉得auto的使用很简单的,其实不然,auto的使用中存在很多的陷阱的。 我们都知道在栈上分配的内存空间,必须进行初始化,不然会导致未定义的行为。有时候我们显示的声明对象的型别,可能会忘记初始化,因此便会出现未定义的行为。有什么办法呢? 有啊~~ 使用auto啊,通...原创 2020-01-30 23:03:46 · 177 阅读 · 0 评论 -
Effective Modern C++ 之 auto和decltype的型别推导
首先我们应该知道auto型别推导的实质就是模板类型推导,在型别推导过程中,把auto替换成T就可以(可以看看我之前写的模板类型推导)。是不是所有的auto都可以与模板的类型推导建立一一映射关系呢?当然不是啦!!auto型别推导中有一条特殊的推导规则。接下来就让我们我们讲一讲啦~~当用auto声明变量,并且该变量用大括号进行初始化时,其推导所得的型别是std::initializer_list&...原创 2020-01-21 10:32:54 · 136 阅读 · 0 评论 -
Effective Modern C++ 之 模板型别推导
模板的型别推到是C++最广泛的特性之一。现在让我们先简单看一个函数模板推导。template<typename T>void fun(PRAMTYPE pram);fun(_parm);这时我们会问T的类型是什么呢?PRAMTYPE的类型又是什么呢?_pram和T的类型,PRAMTYPE的类型存在什么关联呢?这时候就要分三种情况去讨论。PRAMTYPE具有指针或...原创 2020-01-14 23:08:00 · 186 阅读 · 0 评论