nullptrnullptr 是一个新的 C++(www.cppentry.com) 关键字,它是空指针常量,它是用来替代高风险的 NULL 宏和 0 字面量的。nullptr 是强类型的:
- void f(int); //#1
- void f(char *);//#2
- //C++(www.cppentry.com)03
- f(0); //调用的是哪个 f
- //C++(www.cppentry.com)11
- f(nullptr) //毫无疑问,调用的是 #2
所有跟指针有关的地方都可以用 nullptr,包括函数指针和成员指针:
- const char *pc=str.c_str(); //data pointers
- if (pc!=nullptr)
- cout<<pc<<endl;
- int (A::*pmf)()=nullptr; //指向成员函数的指针
- void (*pmf)()=nullptr; //指向函数的指针
委托构造函数C++(www.cppentry.com)11 中构造函数可以调用同一个类的另一个构造函数:
- class M //C++(www.cppentry.com)11 delegating constructors
- {
- int x, y;
- char *p;
- public:
- M(int v) : x(v), y(0), p(new char [MAX]) {} //#1 target
- 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 意义就有巨大的性能提升,如原方案是这样的:
- void naiveswap(string &a, string & b)
- {
- string temp = a;
- a=b;
- b=temp;
- }
这种方案很傻很天真,很慢,因为需要申请内存,然后拷贝字符,而 move 就只需要交换两个数据成员,无须申请、释放内存和拷贝字符数组:
- 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);
- }
要实现支持 move 的类,需要声明 move 构造函数和 move 赋值操作符,如下:
- class Movable
- {
- Movable (Movable&&); //move constructor
- Movable&& operator=(Movable&&); //move assignment operator
- };
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(),下面是例子:
- #include <algorithm>
- //C++(www.cppentry.com)11 code
- //are all of the elements positive
- all_of(first, first+n, ispositive()); //false
- //is there at least one positive element
- any_of(first, first+n, ispositive());//true
- // are none of the elements positive
- none_of(first, first+n, ispositive()); //false
还有一个新的 copy_n:
- #include <algorithm>
- int source[5]={0,12,34,50,80};
- int target[5];
- //从 source 拷贝 5 个元素到 target
- copy_n(source,5,target);
iota() 算法可以用来创建递增序列,它先把初值赋值给 *first,然后用前置 ++ 操作符增长初值并赋值到给下一个迭代器指向的元素,如下:
- #include <numeric>
- int a[5]={0};
- char c[3]={0};
- iota(a, a+5, 10); //changes a to {10,11,12,13,14}
- 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)。 |