设为首页 加入收藏

TOP

C++11中值得关注的几大变化(二)
2011-12-10 21:53:02 来源: 作者: 【 】 浏览:1248
Tags:值得 关注 变化
 

nullptr

nullptr 是一个新的 C++(www.cppentry.com) 关键字,它是空指针常量,它是用来替代高风险的 NULL 宏和 0 字面量的。nullptr 是强类型的:

  1. void f(int); //#1  
  2. void f(char *);//#2  
  3. //C++(www.cppentry.com)03  
  4. f(0); //调用的是哪个 f   
  5. //C++(www.cppentry.com)11  
  6. f(nullptr) //毫无疑问,调用的是 #2  

所有跟指针有关的地方都可以用 nullptr,包括函数指针和成员指针:
  1. const char *pc=str.c_str(); //data pointers  
  2. if (pc!=nullptr)  
  3.   cout<<pc<<endl;  
  4. int (A::*pmf)()=nullptr; //指向成员函数的指针  
  5. void (*pmf)()=nullptr; //指向函数的指针  

 

委托构造函数

C++(www.cppentry.com)11 中构造函数可以调用同一个类的另一个构造函数:

  1. class M //C++(www.cppentry.com)11 delegating constructors  
  2. {  
  3.  int x, y;  
  4.  char *p;  
  5. public:  
  6.  M(int v) : x(v), y(0),  p(new char [MAX])  {} //#1 target  
  7.  M(): M(0) {cout<<"delegating ctor"<<end;} //#2 delegating  

#2 就是所谓的委托构造函数,调用了真正的构造函数 #1。

 

右值引用

在 C++(www.cppentry.com)03 中的引用类型是只绑定左值的,C++(www.cppentry.com)11 引用一个新的引用类型叫右值引用类型,它是绑定到右值的,如临时对象或字面量。
增加右值引用的主要原因是为了实现 move 语义。与传统的拷贝不同,move 的意思是目标对象“窃取”原对象的资源,并将源置于“空”状态。当拷贝一个对象时,其实代价昂贵且无必要,move 操作就可以替代它。如在 string 交换的时候,使用 move 意义就有巨大的性能提升,如原方案是这样的:

  1. void naiveswap(string &a, string & b)  
  2. {  
  3.  string temp = a;  
  4.  a=b;  
  5.  b=temp;  
  6. }  

这种方案很傻很天真,很慢,因为需要申请内存,然后拷贝字符,而 move 就只需要交换两个数据成员,无须申请、释放内存和拷贝字符数组:
  1. void moveswapstr(string& empty, string & filled)  
  2. {  
  3. //pseudo code, but you get the idea  
  4.  size_t sz=empty.size();  
  5.  const char *p= empty.data();  
  6. //move filled's resources to empty  
  7.  empty.setsize(filled.size());  
  8.  empty.setdata(filled.data());  
  9. //filled becomes empty  
  10.  filled.setsize(sz);  
  11.  filled.setdata(p);  
  12. }  

要实现支持 move 的类,需要声明 move 构造函数和 move 赋值操作符,如下:
  1. class Movable  
  2. {  
  3. Movable (Movable&&); //move constructor  
  4. Movable&& operator=(Movable&&); //move assignment operator  
  5. };  

C++(www.cppentry.com)11 的标准库广泛使用 move 语义,很多算法和容器都已经使用 move 语义优化过了。

 

C++(www.cppentry.com)11 的标准库

除 TR1 包含的新容器(unordered_set, unordered_map, unordered_multiset, 和unordered_multimap),还有一些新的库,如正则表达式,tuple,函数对象封装器等。下面介绍一些 C++(www.cppentry.com)11 的标准库新特性:

线程库

从程序员的角度来看,C++(www.cppentry.com)11 最重要的特性就是并发了。C++(www.cppentry.com)11 提供了 thread 类,也提供了 promise 和 future 用以并发环境中的同步,用 async() 函数模板执行并发任务,和 thread_local 存储声明为特定线程独占的数据,这里(http://www.devx.com/SpecialReports/Article/38883)有一个简单的 C++(www.cppentry.com)11 线程库教程(英文)。

新的智能指针类

C++(www.cppentry.com)98 定义的唯一的智能指针类 auto_ptr 已经被弃用,C++(www.cppentry.com)11 引入了新的智能针对类 shared_ptr 和 unique_ptr。它们都是标准库的其它组件兼容,可以安全地把智能指针存入标准容器,也可以安全地用标准算法“倒腾”它们。

新的算法

主要是 all_of()、any_of() 和 none_of(),下面是例子:

  1. #include <algorithm>  
  2. //C++(www.cppentry.com)11 code  
  3. //are all of the elements positive   
  4. all_of(first, first+n, ispositive()); //false  
  5. //is there at least one positive element   
  6. any_of(first, first+n, ispositive());//true  
  7. // are none of the elements positive   
  8. none_of(first, first+n, ispositive()); //false  

还有一个新的 copy_n:
  1. #include <algorithm>  
  2. int source[5]={0,12,34,50,80};  
  3. int target[5];  
  4. //从 source 拷贝 5 个元素到 target  
  5. copy_n(source,5,target);  

iota() 算法可以用来创建递增序列,它先把初值赋值给 *first,然后用前置 ++ 操作符增长初值并赋值到给下一个迭代器指向的元素,如下:
  1. #include <numeric>  
  2. int a[5]={0};  
  3. char c[3]={0};  
  4. iota(a, a+5, 10); //changes a to {10,11,12,13,14}  
  5. iota(c, c+3, 'a'); //{'a','b','c'}  

是的,C++(www.cppentry.com)11 仍然缺少一些很有用的库如 XML API,socket,GUI、反射——以及自动垃圾收集。然而现有特性已经让 C++(www.cppentry.com) 更安全、高效(是的,效率更高了,可以参见 Google 的 基准测试结果http://www.itproportal.com/2011/06/07/googles-rates-c-most-complex-highest-performing-language/)以及更加易于学习和使用。
如果觉得 C++(www.cppentry.com) 变化太大了,不必惊恐,花点时间来学习就好了。可能在你融会贯通新特性以后,你会同意 Stroustrup 的观点:C++(www.cppentry.com)11 是一门新的语言——一个更好的 C++(www.cppentry.com)。

 

首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++11 候选变更 下一篇为std::tuple添加格式化

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: