C++终章:探讨C++ 11 新标准

您所在的位置:网站首页 char在c++中的用法 C++终章:探讨C++ 11 新标准

C++终章:探讨C++ 11 新标准

2023-01-31 08:53| 来源: 网络整理| 查看: 265

一、前述

此为《C++ Primer Plus(第6版)》一书的终章,本章对前面学习的一些C++11新性能做了提要总结,并针对移动语义、包装器、lambda表达式等新性能做了专门的拓展和介绍,本白在下文中也会针对这些一一做简单的回顾,简单的则一笔带过~

二、C++新标准:内容回顾 2.1 统一初始化

统一初始化则是在参数初始化采用初始化列表{}的形式进行,进行/不进行=;初始化列表可使用于基本数据类型、new与类对象。必须注意初始化列表的方法在数据长度缩短时不支持类型转化:

char a = 1234324234;//warning char a = {1234324234};//error!从int到char需要收缩转换!

C++11针对初始化列表的方式专门提供了std::initializer_list方法,常见的String,Vector都支持。拿vector举例,查看STL源码,从vector的构造函数编写中可以看出初始化列表也支持begin()和end(),并且此方法只能在vector类构造函数中使用:

2.2 声明 2.2.1 decltype

decltype这将会把变量的类型定义为表达式指定的类型:

int a; double b; decltype(a) c;//int decltype(a*b) c;//double 2.2.2 auto与后置声明

首先来说又爱又恨的auto,参阅过一些大佬的文章,总结下来auto提高了编程的便利性,但是auto增加了代码的漏洞和可读性,就像是一把双刃剑!个人目前也只是在迭代器中用到了auto,有个比较好玩的事情是,很多大佬都认为,当C++50的时候,C++将进化为:

#inlclude int main(void) { auto; }

不开玩笑,参考各位大佬的建议,使用auto时最好使用后置返回,这样会让人看的很爽:

auto sum_value() ->long double; auto sum_value(int a) ->decltype(a);

代码中sum_value的第二种声明中使用了后置语法,后置语法部分人认为这是C++倒退的体现,但是正好可以弥补auto声明不宜阅读的缺点。

2.2.4 模板别名using

给迭代器等标识符起别名,我感觉没用~这样会降低可读性~

using itype = vector::iterator; 2.3 智能指针

智能指针主要是为了自动处理堆内存而设置的。拿string来说,如果足够仔细和谨慎,在每一个string类对象使用完毕时都合理delete,那就不需要智能指针~可惜人无完人。智能指针一般常指:unique_ptr、shared_ptr、auto_ptr。从书中的示例图可以看出,智能指针可以保证类对象释放时对应的内存空间也释放,这在后文逐一介绍:

三种智能指针中auto_ptr,这已经被遗弃;unique_ptr使用于一个智能指针指向一个类对象的场景;shared_ptr使用于当多个指针指向同一个类对象的场景,这是因为当多个指针指向同一个类对象时,会发生同一内存空间被多次释放的问题,因为基于unique_ptr发展了更高级的指针shared_ptr,shared_ptr具备记录类对象是否过期的功能。除此之外,为了避免多次释放,也可以采用记录所有权或执行深拷贝的方式实现。

2.4 异常规范的修改

加入了noexpect来指明函数不抛出异常~

void sum_value() noexcept;//此函数内部不会抛出异常 2.5 作用域枚举

当使用传统枚举时,我们必须注意同一作用域内枚举名称重复的情况,C++为枚举值也引入了作用域的概念,这样在使用时就不会发生名称冲突:

enum class ar { aa, bb }; enum class ac { aa, bb }; ar::aa; ac::aa; enum struct af { aa, bb };//同class enum struct ag { aa, bb }; af::aa; ac::aa; 2.6 对类的修改

显示转换运算符explicit,声明类转换函数只支持显式转换

初始化成员列表

2.7 右值引用

支持引用右值

三、C++新标准:移动语义 3.1 基础实现

移动语义用于移动,深/浅拷贝用于复制。对于转移数据的场景来说移动语义(转交所有权)的操作更快!何时需要移动,何时需要拷贝赋值呢?这就是右值引用的作用。在右值赋值左值进行移动的优越性远大于先创建临时对象再赋值。来一起看一下移动语义的实现:

示例~ #include #include using namespace std; class cpmv { public: struct info { string qcode; string zcode; }; public: cpmv(); ~cpmv(); cpmv(string q,string z); cpmv(const cpmv &cp); cpmv(cpmv&& mv); cpmv& operator= (const cpmv& cp); cpmv& operator= (cpmv && mv); cpmv operator+(const cpmv &obj) const; void display() const; private: info* pi; }; //默认构造-sj cpmv::cpmv() { cout qcode; pi->zcode = cp.pi->zcode; } //移动构造函数-sj cpmv::cpmv(cpmv&& mv) { cout pi = new info; pi->qcode = cp.pi->qcode; pi->zcode = cp.pi->zcode; return *this; } //赋值运算符移动构造-sj cpmv& cpmv::operator= (cpmv&& mv) { cout pi = mv.pi;//移交所有权 mv.pi = nullptr; return *this; } //加法运算符重载-sj cpmv cpmv::operator+(const cpmv& obj) const { cout qcode += obj.pi->qcode, this->pi->zcode += obj.pi->zcode); } int main(void) { cpmv pv1("zhangwwei", "a2222"); cpmv pv2("lalal", "lalal"); cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3