从C++出来到现在已经13年了。
Bjarne Stroustrup(C++的创造者)最近评价C++:”感觉像个新的语言“。
事实上,C++11核心已经发生了很重大的变化:
. 支持Lambda表达式( lambda expressions)
. 对象自动类型推导(automatic type deduction of objects)
. 统一初始化语法(uniform initialization syntax)
. 代理构造(delegating constructors)
. deleted 和defaulted函数声明(deleted and defaulted function declarations)
. 空指针(nullptr)
. 右值引用(rvalue references)
. ... C++11的标准库也已经修订,使用了新的算法,新的容器类,原子操作,类型,
正则表达式,智能指针, async() 功能,及多线程库。 关于C++11核心和库的新特性的完整描述,请见以下网址:
http://www2.research.att.com/~bs/C++0xFAQ.html . Lambda表达式(Lambda Expressions)
Lambda表达式允许你在本地定义函数,即在调用的地方定义, 从而消除函数对象产生的许多安全风险,Lambda表达式的格式如下: [capture](parameters)->return-type {body}
[]里是函数调用的参数列表,表示一个Lambda表达式的开始, 让我们来看一个Lambda例子: 假 设你想计算某个字符串包含多少个大写字母,使用for_each()遍历一个char数组, 下面的Lambda表达式确定每个字母是否是大写字母,每当它 发现一个大写字母, Lambda表达式给Uppercase加1,Uppercase是定义在Lambda表达式外的一个变量: int main()
{
char s[]="Hello World!";
int Uppercase = ; //modified by the lambda
for_each(s, s+sizeof(s), [&Uppercase] (char c) { if (isupper(c)) Uppercase++; } )
; // 这大括号很容易看走眼的,这代码怎么规范好呢? cout<< Uppercase<<" uppercase letters in: "<< s<<endl;
}
以上例子就好像你在一个函数调用内部定义了一个新的函数。[&Uppercase]中的“&”记号 意味着Lambda主体获得一个 Uppercase的引用,以便它能修改,如果没有这个特殊记号, Uppercase将通过值传递,C++ Lambda表达式也包括成员函数构造器。 . 自动类型推导和声明类型(decltype) 在C++03中,在声明对象时,你必须指定对象的类型,然而,在许多情况下, 对象声明时都有初始化,C++11利用了这个优势,允许你声明对象时不指定类型: auto x=; // x has type int because 0 is int
auto c='a'; // char
auto d=0.5; // double
auto national_debt=14400000000000LL; //long long
自动类型推导主要用于对象类型很长很麻烦的时候,或者是对象是自动生成的
时候(使用模板时)
考虑下面迭代器的声明: void fucn(const vector<int> &vi)
{
vector<int>::const_iterator ci=vi.begin();
}
有了自动类型推导后,你可以这样声明:
auto ci=vi.begin(); // 哈哈,省事了
关 键字auto不是什么新生事物,我们早已认识,它实际上可以追溯到前ANSI C时代, 但是,C++11改变了它的含义,auto不再指定自动存储类型对象,相反,它声明的对象 类型是根据初始化代码推断而来的,C++11删除了 auto关键字的旧有含义以避免混淆。 注意了:auto已经不再是当年的auto了! C++11提供了一个类似的机制捕捉对象或表达式的类型,新的操作符decltype需要一个 表达式,并返回它的类 型。 const vector<int> vi; typedef decltype (vi.begin()) CIT; CIT another_const_iterator;
. 统一初始化语法(uniform initialization syntax)
C++至少有4个不同的初始化符号,有些存在重叠, 括号初始化语法如下: std::string s("hello");
int m=int(); //default initialization
在某些情况下,你也可以使用“=”符号进行初始化: std::string s="hello";
int x=;
对于POD聚合,你还可以使用大括号: int arr[]={,,,};
struct tm today={};
最后,构造函数使用成员进行初始化: struct S {
int x;
S(): x() {}
};
显然,这么多种初始化方法会引起混乱,对新手来说就更痛苦了,更糟糕的是, 在C++03中,你不能初始化POD数组成员,POD数组使用new[]分配, C++11使用统一的大括号符号清理了这一混乱局面。 class C {
int a;
int b;
public:
C(int i, int j);
};
C c {,}; //C++11 only. Equivalent to: C c(0,0);
int* a = new int[] { , , }; //C++11 only
class X {
int a[];
public:
X() : a{,,,} {} //C++11, member array initializer
};
对于容器,你可以和一长串的push_back()调用说再见了,在C++11中, 你可以直观地初始化容器: // C++11 container initializer
vector vs<string>={ "first", "second", "third"};
map singers = { {"Lady Gaga", "+1 (212) 555-7890"},
{"Beyonce Knowles", "+1 (212) 555-0987"}};
类似地,C++11支持成员在类内初始化: class C { int a=; //C++11 only 这和Java一样 public: C(); }; . 代理构造(delegating constructors) 在C++11中,构造函数可以调用类中的其它构造函数: class M //C++11 delegating constructors
{
int x, y;
char *p;
public:
M(int v) : x(v), y(), p(new char [MAX]) {} //#1 target
M(): M() {cout<<"delegating ctor"<
构造函数#,代理构造函数,调用目标构造函数#。 . deleted 和defaulted函数声明(deleted and defaulted function declarations) 一个结构体中的函数: struct A {
A()=default; //C++11
virtual ~A()=default; //C++11
};
对于被称为defaulted的函数,“=default;”部分告诉编译器为函数生成默认实现。 Defaulted函数有两个好处:比手工实现更高效,让程序员摆脱了手工定义这些函数的麻烦事。 与defaulted函数相反的是deleted函数: int func()=delete;
Deleted函数对防止对象复制很有用,回想一下C++自动为类声明一个拷贝构造函数和一个赋值操作符, 要禁用拷贝,声明这两个特殊的成员函数为=delete即可: struct NoCopy {
NoCopy & operator =( const NoCopy & ) = delete;
NoCopy ( const NoCopy & ) = delete;
};
NoCopy a;
NoCopy b(a); //compilation error, copy ctor is deleted . 空指针(nullptr) 终于,C++有了一个指定空指针常量的关键字,nullptr取代了有错误倾向的NULL宏和0, 这两个空指针替代品已经使用很多年了,nullptr是一个强类型: void f(int); //#1
void f(char *); //#2
//C++03
f(); //which f is called? 0可能是int,也可能是空指针,调谁?
//C++11
f(nullptr) //unambiguous, calls #2 这下好了,空指针只能是nullptr。
nullptr适用于所有指针类别,包括函数指针和成员指针: const char *pc=str.c_str(); //data pointers
if (pc!=nullptr)
cout<<pc<<endl;
int (A::*pmf)()=nullptr; //pointer to member function
void (*pmf)()=nullptr; //pointer to function . 右值引用(rvalue references) C++03中的引用类型只能绑定左值,C++11引入了一种新的引用类型,叫做右值引用,
右值引用可以绑定右值,例如,临时对象和字符串。
增加右值 引用的主要原因是移动语义(move semantics),与传统的复制不一样,
移动意味着目标对象偷窃了源对象的资源, 留下一个状态为“空”的源对象。
在某些情况下,复制 一个对象既代价高又没有必要,这时可以用一个移动操作代替。
如果你想评估移动语义(move semantics)带来的性能收益,可以考虑字符串交换,
一个幼稚的实现如下:
void naiveswap(string &a, string & b)
、 {
string temp = a;
a=b;
b=temp;
}
这样的代价很高,复制字符串必须分配原始内存,将字符从源拷贝到目标。 相反,移动字符串仅仅是交换两个数据成员,不用分配内存,拷贝char数组和删除内存: void moveswapstr(string& empty, string & filled) { //pseudo code, but you get the idea size_t sz=empty.size(); const char *p= empty.data(); //move filled's resources to empty empty.setsize(filled.size()); empty.setdata(filled.data()); //filled becomes empty filled.setsize(sz); filled.setdata(p); } 如果你实现的类支持移动,你可以像以下那样声明一个移动构造函数和一个移动赋值操作符: class Movable
{
Movable (Movable&&); //move constructor
Movable&& operator=(Movable&&); //move assignment operator
};
C++11标准库广泛的使用了移动语义,许多算法和容器都为移动做了优化。

c++11新特性(了解)的更多相关文章

  1. C++ 11学习和掌握 ——《深入理解C++ 11:C++11新特性解析和应用》读书笔记(一)

    因为偶然的机会,在图书馆看到<深入理解C++ 11:C++11新特性解析和应用>这本书,大致扫下,受益匪浅,就果断借出来,对于其中的部分内容进行详读并亲自编程测试相关代码,也就有了整理写出 ...

  2. C++11新特性总结 (二)

    1. 范围for语句 C++11 引入了一种更为简单的for语句,这种for语句可以很方便的遍历容器或其他序列的所有元素 vector<int> vec = {1,2,3,4,5,6}; ...

  3. C++11新特性总结 (一)

    1. 概述 最近在看C++ Primer5 刚好看到一半,总结一下C++11里面确实加了很多新东西,如果没有任何了解,别说自己写了,看别人写的代码估计都会有些吃力.C++ Primer5是学习C++1 ...

  4. C++ 11 新特性

    C++11新特性:          1.auto          2.nullptr          3.for          4.lambda表达式          5.override ...

  5. [转载] C++11新特性

    C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...

  6. 在C++98基础上学习C++11新特性

    自己一直用的是C++98规范来编程,对于C++11只闻其名却没用过其特性.近期因为工作的需要,需要掌握C++11的一些特性,所以查阅了一些C++11资料.因为自己有C++98的基础,所以从C++98过 ...

  7. C++11新特性——range for

    很多编程语言都有range for语法功能,自C++11起,终于将这个重要功能加入C++标准中.range for语句,可以方便的遍历给定序列中的每个元素并对其执行某种操作. 1.基本语法 for(d ...

  8. C++11新特性——大括号初始化

    C++11之前,C++主要有以下几种初始化方式: //小括号初始化 string str("hello"); //等号初始化 string str="hello" ...

  9. C++11新特性之六——元编程

    C++11新特性之六——元编程

  10. C++11新特性之一——Lambda表达式

    C++11新特性总结可以参考:http://www.cnblogs.com/pzhfei/archive/2013/03/02/CPP_new_feature.html#section_6.8 C++ ...

随机推荐

  1. 错题726-java

    class Car extends Vehicle { public static void main (String[] args) { new Car(). run(); } private fi ...

  2. [转]iOS 应用内付费(IAP)开发步骤

    FROM : http://blog.csdn.net/xiaoxiangzhu660810/article/details/17434907 参考文章链接: (1)http://mobile.51c ...

  3. [转]服务器自动化操作 RunDeck

    From : http://www.oschina.net/p/rundeck/similar_projects?sort=view&lang=25 RunDeck 是用 Java/Grail ...

  4. U3D 扩展方法 & Dotween & tolua

    using UnityEngine; using System.Collections; using LuaInterface;//tolua 空间引用 using DG.Tweening;//DOT ...

  5. C#关于MSMQ通过HTTP远程发送专有队列消息的问题

    两台计算机的操作系统都是Windows Server 2008两台计算机都安装了MSMQ+Http支持两台计算机的防火墙全部关闭本地Ip:192.168.1.104远程Ip:192.168.1.142 ...

  6. [CareerCup] 7.7 The Number with Only Prime Factors 只有质数因子的数字

    7.7 Design an algorithm to find the kth number such that the only prime factors are 3,5, and 7. 这道题跟 ...

  7. WPF Binding INotifyPropertyChanged 多线程 深入理解

    例子 先来看一个例子 Person.cs public class Person : ObservableObject,INotifyPropertyChanged { private string ...

  8. Javascript的字面量对象以及如何拆解字面量对象

    简单的说,字面量对象提供了一直非常方便构建新对象的方式,它的格式非常简单且容易阅读.是大多数前端程序员在构建对象时比较推崇的一种方式. 格式: var person = { name : " ...

  9. Jenkins入门系列之——00答疑解惑

    写在最前的总结:Jenkins其实就是一个工具,这个工具的作用就是调用各种其他的工具来达成你的目的.比如你要获取Subversion上最新的源代码,Jenkins会去调用SVNKIT(插件的核心Jar ...

  10. 服务发现:Zookeeper vs etcd vs Consul

    [编者的话]本文对比了Zookeeper.etcd和Consul三种服务发现工具,探讨了最佳的服务发现解决方案,仅供参考. 如果使用预定义的端口,服务越多,发生冲突的可能性越大,毕竟,不可能有两个服务 ...