技术开发 频道

C++0x探秘:访C++之父Bjarne Stroustrup

  在我们从C++0x的简化中获得好处之前,也许我们会经历这样一个黑暗的时期——很多人会通过列举C++0x的新的语法规则或者是孔乙己式地深究C++0x的语法细节来展示自己的“聪明才智”。实际上,这样做是有害的。

  我们不能指望人们仅仅通过阅读就能对C++0x编程有一个很好的理解。人们必须在开发实践中真正地使用这些新特性。幸运的是,C++0x的很多新特性已经在很多编译器(例如,GCC和Microsoft Visual C++)中实现了。C++0x不是象牙塔中的科学研究,而是真实地来到了我们身边。!

  Danny Kalev: 总体而言,你认为将右值引用添加到C++0x是值得的吗?除了性能的提升之外,一个典型的C++程序员还能从右值引用中获得什么其他的好处呢?比如更简洁的设计,更简单的算法等等?

  Bjarne Stroustrup: 我觉得将右值引用加入C++0x,不仅仅是值得,而是非常值得。移动语义可以作为一个长期存在的问题——如何从函数中返回一个体积较大的数据结构——的解决方案。对于这个问题,移动语义给了我们一个显而易见的,简单而高效的答案:直接将结果从函数中移动到目标位置;不需要复制结果;不需要在内存管理上玩什么技巧;不需要使用混乱的特殊用途的内存管理方案;不需要函数的调用者预先申请内存;不需要通过额外的参数进行值的传递;不需要任何形式的垃圾回收机制。我认为这是右值引用的两个应用中的最重要的一个。它将影响我们使用C++进行开发的每一个人,并且会让我们的生活变得更好。开玩笑地说,以前很多人都说“聪明的程序员才能使用C++”,现在,有了移动语义,不那么“聪明”的程序员也可以使用C++了。我们可以省掉我们的聪明了。

  值得注意的是,写一个有关右值引用移动的操作通常是一件非常简单的事情,它不像送火箭上天那么困难啦。

  class Matrix {

  
double* elem; // 指向成员变量的指针

  
int dim1, dim2;

  
public:

  Matrix(Matrix
&& a)

  :dim1(a.dim1), dim2(a.dim2), elem(a.elem)
// 移动数据

  { a.dim1
=0; a.dim2=0; a.elem=nullptr; } // 将原来的数据清空

  
// ….

  };

  这就是整个移动构造函数的完整过程:移动数据并将原来的数据清空。有了它的帮助,我们甚至可以简单而高效地返回一个10000*10000的矩阵。

  当然,对于程序库的开发者而言这也将是非常重要的一天:在程序库中,有很多地方可以使用移动语义以简化程序库的实现,并且在更多的地方,转发(右值引用的另外一个重要应用)将有助于程序库的设计与实现。并且,移动语义和完美转发并不是只有专家才能掌握的高深技术,每一个C++程序员都可以使用它们来简化我们的程序,提高程序的性能。

0
相关文章