C++11 能好怎?
0. 摘要
近期读了一些关于C++11标准的材料。 本篇博客将从新标准的优点、与旧版本的区别和使用方法三个角度,大致介绍我对C++11的认识。
C++11标准,原名C++0x, 是03版旧标准的更新。总结来说,新标准给我更加接近脚本语言的感觉。move语义的支持、auto关键字自动类型等新特性,使得C++11在性能和效率上比旧版本有更大优势。
我参考的博客和网页有:
http://www.csdn.net/article/2012-05-15/2805585
http://stackoverflow.com/questions/1930903/bind-vs-lambda
http://baike.baidu.com/link?url=IsEuVplXgGEw6H_tjyGU2pKIKffDw8Sry0aZd9btV8O5upyzGRofxXDviB9RI5C-XYpNY7tzAD9KAZLW8fW4n_
http://blog.csdn.net/lancelet/article/details/7220558
http://zh.wikipedia.org/wiki/C++0x
http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx
http://msdn.microsoft.com/en-us/library/vstudio/hh567368.aspx
http://herbsutter.com/elements-of-modern-c-style/
http://en.wikipedia.org/wiki/C%2B%2B11
1. C++11 新特性概述
下面简要介绍对我来说意义较为明显的几点
1. 右值引用和move语义(move semantics)。它是优化复制的一种方式。在很多时候,深度复制是低效率的行为,而move语义将允许简单的复制指针到字符缓冲区,减少在内存配置上使用的时间。获取右值必须使用std::move<T>().举例:
bool is_r_value(int &&) { return true; }
bool is_r_value(const int &) { return false; }
void test(int && i)
{
is_r_value(i); // i 為具名變數,即使被宣告成右值也不會被認定是右值。
is_r_value(std::move<int&>(i)); // 使用 std::move<T>() 取得右值。
}
2. 类型推导:auto关键字。auto关键字可以使得我们再也不必根据右值复杂的表达式推断左值的类型。它的意义在于大大增加了代码可读性,并且节省了很多无意义的开发时间,而将数据类型的推测交给编译器来做。
举例而言,原本我们这样的表达:
for(vector<int>::const_iterator itr = myvec.begin(); itr != myvec.end();++itr)
可以简化为:
for(auto itr = myvec.begin(); itr != myvec.end();++itr)
decltype可以得到参数实例的数据类型,与auto弥补:
#include <vector> int main()
{
const std::vector<int> v();
auto a = v[];// a 为 int 类型
decltype(v[]) b =; // b 为 const int& 类型,即std::vector<int>::operator[](size_type)const 的返回类型
auto c =; // c 为 int 类型
auto d = c; // d 为 int 类型
decltype(c) e; // e 为 int 类型,c 实体的类型
decltype((c)) f = e; // f 为 int& 类型,因为(c)是左值
decltype() g; // g为int类型,因为0是右值
return ;
}
3. smart pointer智能指针。智能指针改善了auto_ptr的问题,使得开发过程不必担心内存释放的问题,处理内存泄露的过程得以简化。
4. 以范围为基础的for循环。for 语句将允许简单的范围迭代:第一部分定义被用来做范围迭代的变量,就像被声明在一般for循环的变量一样,其作用域仅只于循环的范围。而在":"之后的第二区块,代表将被迭代的范围。这样一来,就有了能够允许C-style数组被转换成范围概念的概念图。这可以是std::vector,或是其他符合范围概念的对象。举例:
原本的表达:
// circle and shape are user-defined types
circle* p = new circle( );
vector<shape*> v = load_shapes(); for( vector<circle*>::iterator i = v.begin(); i != v.end(); ++i ) {
if( *i && **i == *p )
cout << **i << “ is a match\n”;
} for( vector<circle*>::iterator i = v.begin();
i != v.end(); ++i ) {
delete *i; // not exception safe
} delete p;
使用新标准,表达相同的过程,可以大大简化:
#include <memory>
#include <vector>
// ...
// circle and shape are user-defined types
auto p = make_shared<circle>( );
vector<shared_ptr<shape>> v = load_shapes(); for_each( begin(v), end(v), [&]( const shared_ptr<shape>& s ) {
if( s && *s == *p )
cout << *s << " is a match\n";
} );
5. lambda表达式。lambda表达式允许如下定义:
[](int x, int y) { return x + y; }
lambda表达式解决了函数内部不得不使用function对象造成的繁琐问题。
6. 空指针的调整。在标准C中,0值兼顾了数值和NULL的双重语义,C++并未继承此规则,不允许将void*隐式转换为其他类型的指针。char*c = NULL;这样的表达无法直观的实现。C++11使用nullptr将0和空指针分离开:
char* pc = nullptr; // OK
int * pi = nullptr; // OK
int i = nullptr; // error foo(nullptr); // 呼叫 foo(char *)
7. C++还有其他很有意义的改进,但因笔者目前接触不到这些改进的意义,仅作简单的列举:
7.1 显示虚函数重载
7.2 对POD定义的修正
7.3 强类型的枚举
7.4 模板别名
7.5 变长参数模板
7.6 正则表达式
3. 总结
C++11,相比于旧版本,主要的提升方面为:1. 语言运行时的表现强化(就是效率更高了) 2. 核心语言使用性加强(就是能写出更简洁的代码) 3. 核心语言能力提升(允许更多的如变长参数模板的表达)
4. 我的问题
lambda表达式不是很透彻..
虚函数重载不知道什么时候用?
其实,我的问题都应该会在新版本的C++Premer中得到解答,这里的疑问只有,在团队编程中,C++11如何与C++03兼容?如果一个项目里面其他的人都使用C++03,或者一个已经写好的程序使用的是C++03,如果做出C++11的改动,能否可行,或者会不会造成问题?
3. 怎么使用?(编译器支持)
新版本的C++经典教程已经对新标准进行了更新,目前主流编译器对C++11 的支持如下:
|
Visual Studio 2010 |
Visual Studio 2012 |
Visual Studio 2013 |
|
|
v2.0 |
v2.1* |
v2.1* |
|
|
No |
No |
No |
|
|
No |
No |
||
|
No |
No |
||
|
No |
No |
||
|
Yes |
Yes |
Yes |
|
|
v1.0 |
v1.0 |
v1.0 |
|
|
Yes |
Yes |
Yes |
|
|
v1.0 |
v1.1 |
v1.1 |
|
|
v1.0 |
v1.1** |
v1.1 |
|
|
Yes |
Yes |
Yes |
|
|
No |
No |
Yes |
|
|
No |
No |
No |
|
|
No |
No |
||
|
Yes |
Yes |
Yes |
|
|
Yes |
Yes |
Yes |
|
|
Partial |
Yes |
Yes |
|
|
No |
Yes |
Yes |
|
|
No |
No |
No |
|
|
No |
No |
No |
|
|
TR1 |
Partial |
Partial |
|
|
No |
No |
||
|
No |
No |
No |
|
|
No |
No |
Yes |
|
|
No |
No |
No |
|
|
No |
No |
No |
|
|
No |
No |
||
|
No |
No |
No |
|
|
No |
No |
No |
|
|
No |
Yes |
Yes |
|
|
No |
No |
||
|
Yes |
Yes |
Yes |
|
|
No |
No |
No |
|
|
No |
No |
No |
|
|
No |
No |
No |
|
|
Yes |
Yes |
Yes |
|
|
No |
Yes |
Yes |
|
|
Partial |
Yes |
Yes |
|
|
Yes |
Yes |
Yes |
|
|
No |
No |
No |
|
C++11 Core Language Features: Concurrency |
Visual Studio 2010 |
Visual Studio 2012 |
Visual Studio 2013 |
|
N/A |
N/A |
N/A |
|
|
No |
Yes |
Yes |
|
|
No |
Yes |
Yes |
|
|
No |
Yes |
Yes |
|
|
N/A |
N/A |
N/A |
|
|
No |
Yes |
Yes |
|
|
No |
No |
No |
|
|
Yes |
Yes |
Yes |
|
|
No |
No |
No |
|
|
No |
No |
No |
|
|
Partial |
Partial |
Partial |
|
|
No |
No |
No |
|
C++11 Core Language Features: C99 |
Visual Studio 2010 |
Visual Studio 2012 |
Visual Studio 2013 |
|
Partial |
Partial |
Partial |
|
|
Partial |
Partial |
Partial |
|
|
Yes |
Yes |
Yes |
|
|
N/A |
N/A |
N/A |
C++11 能好怎?的更多相关文章
- 地区sql
/*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...
- WinForm 天猫2013双11自动抢红包【源码下载】
1. 正确获取红包流程 2. 软件介绍 2.1 效果图: 2.2 功能介绍 2.2.1 账号登录 页面开始时,会载入这个网站:https://login.taobao.com/member/login ...
- C++11特性——变量部分(using类型别名、constexpr常量表达式、auto类型推断、nullptr空指针等)
#include <iostream> using namespace std; int main() { using cullptr = const unsigned long long ...
- CSS垂直居中的11种实现方式
今天是邓呆呆球衣退役的日子,在这个颇具纪念意义的日子里我写下自己的第一篇博客,还望前辈们多多提携,多多指教! 接下来,就进入正文,来说说关于垂直居中的事.(以下这11种垂直居中的实现方式均为笔者在日常 ...
- C++ 11 多线程--线程管理
说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...
- CSharpGL(11)用C#直接编写GLSL程序
CSharpGL(11)用C#直接编写GLSL程序 +BIT祝威+悄悄在此留下版了个权的信息说: 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharp ...
- ABP(现代ASP.NET样板开发框架)系列之11、ABP领域层——仓储(Repositories)
点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之11.ABP领域层——仓储(Repositories) ABP是“ASP.NET Boilerplate Proj ...
- C++11 shared_ptr 智能指针 的使用,避免内存泄露
多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...
- C++11网络编程
Handy是一个简洁优雅的C++11网络库,适用于linux与Mac平台.十行代码即可完成一个完整的网络服务器. 下面是echo服务器的代码: #include <handy/handy.h&g ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(11)-系统日志和异常的处理①
系列目录 系统需要越来越自动化,我们需要引入日志记录和异常捕获管理员的操作记录需要被记录,看出哪些模块是频繁操作,分析哪些是不必要的功能,哪些是需要被优化的.系统的异常需要被捕获,而不是将系统出错显示 ...
随机推荐
- struct hw_module_t HAL_MODULE_INFO_SYM
先开个头,准备这与一篇struct hw_module_t HAL_MODULE_INFO_SYM 相关的文章. Hal层的库文件是怎么被上层调用的?上层调用时的入口(相当于main)又是什么呢?它就 ...
- input默认提示取消
input 输入框有提示功能,当你之前输入过一些内容,你下次打入相关字符的时候,默认会有之前输入的一些相关的字符的提示,这个提示一般来说还是很好的,但是,有时候,我们想自己输入,不想要提示. 如果不需 ...
- UVa 12034 (递推) Race
题意: 有n个人赛马,名次可能并列,求一共有多少种可能. 分析: 设所求为f(n),假设并列第一名有i个人,则共有C(n, i)种可能,接下来确定后面的名次,共有f(n-1)种可能 所以递推关系为: ...
- 前端SPA框架一些看法
说起前端框架,我个人主张有框架不如无框架,这个观点要先从框架和库的区别说起. 我所理解的库,解决的是代码或是模块级别的复用或者对复杂度的封装问题;而框架,更多的是对模式级别的复用和对程序组织的规范,这 ...
- sqlserver错误"试图扩大物理文件时,MODIFY FILE 遇到操作系统错误 112(磁盘空间不足。)。"处理
正常还原的时候报错: Microsoft SQL-DMO (ODBC SQLState: 42000)---------------------------试图扩大物理文件时,MODIFY FILE ...
- json格式的字符串使用string.Format()方法报错:输入字符串的格式不正确
解决:把大括号转义一下就可以了啊,大括号的转义是两个{{ 结尾是}} 今天看同事写的代码,发现他在使用string.format拼接类似json格式的数据时,大括号多了一对,感觉不对就查了查 ...
- uva 11768
// 扩展欧几里得算法 // 先求出一个解 再求出区间 [x1,x2]有几个整数符合条件// 需要注意的是 水平和垂直2种情况的处理 还有正数和负数取整的细微差别#include <iostre ...
- 在delphi中, reintroduce作用
在delphi中, reintroduce作用 当在子类中重载或者重新声明父类的虚方法时,使用 reintroduce 关键字告知编译器,可以消除警告信息.如: TPar ...
- ECSHOP seo修改建议
ECSHOP是一个非常优秀的商城程序,以丰富的模板.稳定开源.非常快的执行速度赢得广大网店主的青眯.可是新建站30多天,目前百度只收录了首页,而google收录正常.我检查了他的网站一切正常,没有任何 ...
- 硬盘结构介绍--mbr及分区
硬盘刚买来使用时需要经过分区然后格式化才能够使用,硬盘经过分区后,分区软件便会写一个主引导扇区,这个扇区位于硬盘的 0 磁道 0 柱面第1扇区(即0区)(注意:该扇区为隐含扇区,0道0面的全部扇区均为 ...