• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C++11的新特性简单汇总介绍 (二)

C++11的新特性简单汇总介绍 (二)

作者:wangqiguo 字体:[增加 减小] 来源:互联网 时间:2017-05-28

wangqiguo 通过本文主要向大家介绍了c++11新特性,visual c++ 11 beta,c++11,c++11标准,c++11编译器等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

1. 范围for语句

C++11 引入了一种更为简单的for语句,这种for语句可以很方便的遍历容器或其他序列的所有元素

vector<int> vec = {1,2,3,4,5,6};
for(int x: vec)
{
  cout<<x<<endl;
}
</div>

2. 尾置返回类型

要想引入尾置类型,我们还得从复杂的类型声明说起。如果我们需要定义一个含有10个int元素的数组,一般是这样的:

int arr[10] = {0};
</div>

如果要定义指向这个数组的指针呢:

int (*p_arr)[10] = &arr; //注意:int *p_arr[10] 表示一个数组,有10个元素,元素类型是int*
</div>

如果要定义一个函数,这个函数接受一个char类型的参数,并返回一个指向10个int类型数组的指针呢:

int (*func(char x))[10];
</div>

这样的声明是不是看的头都大了,其实我们可以简化一点,一般情况下我们可以使用别名进行简化,比如:

typedef int ARR[10] ; // 定义一个类型 ARR这是一个数组类型,含有10个int类型的元素
using ARR = int[10] ; // 同上
</div>

再定义如上的函数:

ARR * func(char x) ; // 函数返回的类型是 ARR* 也就是指向具有10个int元素数组的指针
</div>

当然在C++11中我们可以用之前讲到过的另外一个关键字decltype:

decltype(arr) * func(char x) ; // decltype(arr)表达式会获得arr的类型
</div>

最后就轮到我们本节要说的C++11的另外一个特性,尾置返回类型,任何函数都可以使用尾置返回类型,这种形式对于返回类型比较复杂的函数最有效,比如上面的函数可以使用如下方式:

auto func(char x) -> int(*) [10];
</div>

这种形式将函数的返回类型写在函数声明的最后面,并且在函数形参列表后面加上 -> 符号,然后紧接着是函数需要返回的类型,由于函数的返回类型被放在了形参列表之后,所以在函数名前面使用一个 auto替代。

3. =default 生成默认构造函数

在C++的类中,如果我们没有定义构造函数,编译器会为我们合成默认的无参构造函数,如果我们定义了构造函数,则编译器就不生成默认构造函数了,但是如果我们定义构造函数同时也希望编译器生成默认构造函数呢? C++11中可以通过在构造函数的声明中直接  =default的方式要求编译器生成构造函数。

class ClassName{
  public:
    ClassName(int x);
    ClassName()=default; // 显示要求编译器生成构造函数
};

</div>

4. 类对象成员的类内初始化

class ClassName
{
    public:
        int x = 10; //C++11 之前是不允许的
};

</div>

5. lambda表达式与bind函数

lambda表达式是一个可以被调用的代码单元,相当于一个内联函数,有参数和返回值以及函数体。但是跟函数不同的是,lambda表达式可以定义在函数的内部,一个完整的lambda表达式具有如下形式:

[捕获列表](参数列表) mutable -> 返回类型 {函数体}

int x = 10;
int y = 20;
auto f = [x,&y](int a ,int b){++y;return a+b+x+y;};
cout<<f(1,2)<<endl; //34
cout<<y<<endl;   //21
</div>

lambda可以省略参数列表(如果没有参数的话),可以省略返回类型,但是不能省略捕获部分与函数体部分,即使捕获列表为空,也要有一个空的[],lambda有两种捕获,一种是值捕获,一种是引用捕获。如果是值捕获那么lambda中获得的是捕获的变量的副本,如果是引用捕获则获得的是引用,可以在lambda内部修改引用的变量的值,如上x是值捕获,y是引用捕获,lambda中默认是值捕获,如果变量前面添加&则是引用捕获,另外lambda中还有两种形式的引用捕获,例如[=]表示值捕获所有可见的变量,而[&]则表示引用捕获所有可见变量。如果希望值捕获所有可见变量,但是又有个别变量采用引用捕获呢,[=,&x]表示值捕获所有可见变量,同时引用捕获x。而[&,x]则表示引用捕获所有可见变量,x采用值捕获的方式。

有关bind函数,在很多地方我们可以使用函数替换lambda表达式,毕竟如果很多地方需要用到同一个lambda表达式,而且这个lambda表达式比较长的话,将其定义成函数应该是最好的。对于没有捕获列表的lambda表达式我们可以直接使用函数替代,例如:

void main()
{
  auto f=[](int x,int y){return x+y};
  f();
}
</div>

我们可以用下面的方式替代:

int f(int x,int y)
{
  return x+y;
}
 
void main()
{
  f();
}
</div>

与上面的lambda是等价的,但是对于有捕获列表的lambda表达式应该怎么处理呢,例如:

void main()
{
  int x = 10;
  int y = 20;
  auto f = [x,&y](int a ,int b){return a+b+x+y;}; //一个值捕获,一个引用捕获
  f(33,44);
}
</div>

如果转换成函数的形式:

int x = 10;
int y = 20;
int f(int a,int b)
{
 return a+bx+y;
}
 
void main()
{
  f(33,44);
}
</div>

这是一种可行的方法,但是总不能把所有的捕获变量定义成全局变量吧。现在的关键问题是lambda的捕获表达式中的内容转换成函数不可行,C++11提供了bind函数来完成这样的操作。

#include <functional> //bind()
#include <iostream>
using namespace std;
using namespace std::placeholders; // _1,_2所在的命名空间
int f(int x,int y,int a,int b)
{
 return a+b+x+y;
}
 
void main()
{
 int x = 10;
 int y = 20;
 
 auto f_wrap = bind(f,x,y,_1,_2);
 cout<<f_wrap(33,44)<<endl; // _1,_2是占位符,表示调用f_wrap的时候_1是第一个参数,_2是第二个参数。最终会被替换成调用 f(10,20,33,44)
}
</div>

如果引用类型的捕获怎么做呢,看下面的例子,用lambda是这样的:

#include <iostream>
#include <functional>
using namespace std;
using namespace std::placeholders;
void main()
{
 int x = 10;
 ostream &o = cout;
 auto f =[&o](int a){o<<a<<endl;}; // 注意这里的输出对象是用的引用捕获
 f(x);
}
</div>

使用bind是这样的:

#include <iostream>
#include <functional>
using namespace std;
using namespace std::placeholders;
void f(ostream &o,int x)
{
 o<<x<<endl;
}
int main()
{
 int x = 10;
 auto f_wrap = bind(f,ref(cout),_1); //将变量的引用传递到bind中是个问题,为此C++11提供了ref()函数用于获得引用
 f_wrap(x);
 return 0 ;
}

</div>

6. 智能指针share_ptr,unique_ptr

C++11中引入了几种智能指针,智能指针能够自动释放所指向的对象,其中shared_ptr允许多个指针指向同一个对象,unique_ptr则独占所指向的对象,我们主要说明shared_ptr的使用。通过使用m

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C++ 11和C++98相比有哪些新特性
  • C++11新特性中auto 和 decltype 区别和联系
  • C++11新特性之auto的使用
  • C++11新特性之智能指针(shared_ptr/unique_ptr/weak_ptr)
  • C++11的新特性简单汇总介绍 (二)
  • C++11的新特性简单汇总介绍 (一)
  • C++11的for循环,以及范围Range类的简单实现
  • 关于C++一些特性的探究
  • 结合C++11新特性来学习C++中lambda表达式的用法
  • 结合C++11的新特性来解析C++中的枚举与联合

相关文章

  • 2017-05-28C语言按关键字搜索文件夹中文件的方法
  • 2017-05-28MFC创建模态对话框和非模态对话框的方法
  • 2017-05-28C语言 指针与二维数组详解
  • 2017-05-28vc提示unexpected end of file found的原因分析
  • 2017-05-28c语言swap(a,b)值交换的4种实现方法
  • 2017-05-28C++静态成员函数不能调用非静态成员变量(详解)
  • 2017-05-28深入理解C++的对象模型
  • 2017-05-28Cocos2d-x学习笔记之世界坐标系、本地坐标系、opengl坐标系、屏幕坐标系
  • 2017-05-28while和for可以相互转换的例子分享
  • 2017-05-28C语言中二维数组指针的简要说明

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • c++回调之利用sink示例
    • 一道超经典的C++结构体的题目
    • 在vs2010中,输出当前文件路径与源文件当前行号的解决方法
    • C++实现单链表删除倒数第k个节点的方法
    • C++实现的分布式游戏服务端引擎KBEngine详解
    • ipv6实现tcp编程示例
    • C数据结构之双链表详细示例分析
    • 深入理解C++的动态绑定与静态绑定的应用详解
    • C++函数重载的深入解析
    • C++虚析构函数的使用分析

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有