频道栏目
首页 > 程序开发 > 软件开发 > C++ > 正文
C++11的新特性介绍
2018-04-16 10:37:34      个评论    来源:saasanken的博客  
收藏   我要投稿

一、auto无法带走cv限制符

在C++标准中,const和volatile被称为“cv限制符,cv-qualifier”,它们分别代表了变量的两种不同的属性“不变的”和“易变的”。C++11标准规定auto可以和cv限制符一起使用,但是声明为auto的变量不能从其初始化表达式中“带走”cv限制符。例如const auto a = 1; 如果我们声明auto b = a; 那么b的类型是int而非const int,这里的例外是引用和指针,如果我们声明auto & c = a; 那么c的类型是const int&,声明为引用的变量依然保持着与其引用的对象相同的属性。

相比之下,decltype则可以带走cv限制符,但如果是一个对象的定义中含有const或volatile限制符,使用decltype进行推导时,其成员不会继承const和volatile。举例说明,const int i=0; 那么decltype(i)是const int,而如果:

struct S { int i; };

const S a = {0};

那么decltype(a)的类型是const S,但是a.i的类型并不是const。

还需要注意的是类型定义时的冗余符号:

int *a;

auto * b = a;,这里b的类型是int *而不是int **,因为在auto声明中,*也可以是冗余的,而如果使用decltype:

decltype(a) *c = &a;//decltype(a) *c = a无法通过编译

c的类型是int **。

二、追踪返回类型

如果一个函数模板的返回类型依赖于实际的入口参数类型,那么该返回类型在模板实例化之前可能都无法确定,这样的话我们在定义该函数模板时就会遇到麻烦。你可能会想到使用decltype来解决下面这个问题:

template
decltype(t1+t2) Sum(T1 &t1, T2 &t2) {
    return t1 + t2;
}

这里的问题是显而易见的,编译期通常并不能预知未来,在推导decltype(t1+t2)的时候,t1和t2还都是未定义的。为了解决这个问题,C++11引入新的语法——追踪返回类型:

template
auto Sum(T1 &t1, T2 &t2) -> decltype(t1+t2) {
    return t1 + t2;
}

这里有一个有趣的例子:

int (*(*pf())())(){ return nullptr; }

auto pf1() -> auto(*)() -> int (*)(){
    return nullptr;
}

这里pf是函数指针的指针,而pf1,从右往左看,auto(*)()-> int (*)()是函数指针,auto pf1() -> ~,pf1显然是前面这一部分的指针,也是函数指针的指针,它们其实是等价的。

auto (*fp)() -> int与int(*fp)()是等价的。auto (&fr)() -> int与int(&fr)()也是等价的。

吐槽,有人说学了C++11再也不怕别人看懂我的代码了,所言非虚。

还记得之前的转发函数吗,之前我们只实现了没有返回值的转发函数,如果要实现有返回值的转发函数,但我们返回值的类型显然是由待转发的内容所决定的,这时候就需要追踪返回类型了:

template
auto Forwarding(T && t) -> decltype(ActualFunc(forward(t))){
    return ActualFunc(forward(t));
}

这样即使ActualFunc存在一些重载的返回值类型不同的版本也可以实现转发。

三、基于范围的for循环

这个不必多言,对于可确定的迭代范围(类实现了begin和end函数),并且迭代对象实现了++,--等操作符,就可以使用基于范围的for循环。

具体形式类似for(int &e : arr)这样,如果不需要改变e的值,可以去掉取引用符号。

四、unique_ptr, shared_ptr, 和weak_ptr

由废弃的auto_ptr发展而来。unique_ptr形如其名,与所指对象的内存紧密绑定,不能与其他unique_ptr类型的指针对象共享所指对象的内存。从实现上来讲,unique_ptr是一个删除了拷贝构造函数、保留了移动构造函数的指针封装类型,我们仅仅可以使用右值引用对unique_ptr进行构造,而且一旦构造成功,右值对象中的指针即被窃取。

shared_ptr同样形如其名,它允许多个该智能指针共享地拥有同一堆分配对象的内存。在实现上,shared_ptr使用了引用计数。可以通过reset方法来减少相应的引用计数。

weak_ptr稍微复杂一点,它可以指向shared_ptr指针指向的对象内存,但并不拥有该内存。而使用weak_ptr的成员lock,可以返回其所指内存的一个shared_ptr对象,若该shred_ptr无效则返回nullptr,这个特性可以用来判断shared_ptr的有效性。

点击复制链接 与好友分享!回本站首页
上一篇:区分C++ 中的引用与指针
下一篇:最后一页
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站