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)-系统日志和异常的处理①
系列目录 系统需要越来越自动化,我们需要引入日志记录和异常捕获管理员的操作记录需要被记录,看出哪些模块是频繁操作,分析哪些是不必要的功能,哪些是需要被优化的.系统的异常需要被捕获,而不是将系统出错显示 ...
随机推荐
- 在Windows 上的 Python
在 Windows 上, 安装 Python 有两种选择. ActiveState 制作了一个 Windows 上的 Python 安装程序称为 ActivePython, 它包含了一个完整的 Pyt ...
- Java连接MySQL数据库及简单操作代码
1.Java连接MySQL数据库 Java连接MySql需要下载JDBC驱动MySQL-connector-java-5.0.5.zip(举例,现有新版本).然后将其解压缩到任一目录.我是解压到D盘, ...
- 学习Hadoop不错的系列文章
1)Hadoop学习总结 (1)HDFS简介 (2)HDFS读写过程解析 (3)Map-Reduce入门 (4)Map-Reduce的过程解析 (5)Hadoop的运行痕迹 (6)Apache Had ...
- JPA和Hibernate的区别
JPA Java Persistence API,是Java EE 5的标准ORM接口,也是ejb3规范的一部分. Hibernate,当今很流行的ORM框架,是JPA的一个实现,但是其功能是JPA的 ...
- zlib用法说明
1. 如何获得zlib zlib的主页是:http://www.zlib.net/ 2. 用VC++6.0打开 把 下载的源代码解压打开,VC6.0的工程已经建好了,在\projects\visual ...
- UVa 11077 (循环分解 递推) Find the Permutations
把{1, 2, 3,,, n}叫做自然排列 本题便是求有多少个n元排列P要至少经过k次交换才能变为自然排列. 首先将排列P看做置换,然后将其分解循环,对于每个长度为i的循环至少要交换i-1次才能归位. ...
- android通过httpClient请求获取JSON数据并且解析
使用.net创建一个ashx文件,并response.write json格式 public void ProcessRequest(HttpContext context) { context.R ...
- Delegate 委托复习(-) 委托的基本概念
1. 声明一个delegate对象,它应当与你想要传递的方法具有相同的参数和返回值类型. 声明一个代理的例子: public delegate int MyDelegate(stri ...
- textview设置字体的行距和字间距
字间距 textView有一个属性android:textScaleX是调节字间距的,它的值是一个float型.查看源代码,默认textView 此属性是使用的是: android.internal. ...
- POJ 3084 Panic Room (最小割建模)
[题意]理解了半天--大意就是,有一些房间,初始时某些房间之间有一些门,并且这些门是打开的,也就是可以来回走动的,但是这些门是确切属于某个房间的,也就是说如果要锁门,则只有在那个房间里才能锁. 现在一 ...