泛型编程-转移构造函数(Generic Programming: Move Constructor)

http://tech.ddvip.com   2007年03月16日    社区交流

本文详细介绍泛型编程-转移构造函数(Generic Programming: Move Constructor)

  这个新版本的不利之处在于,现在调用Connect也许生成了更多的机器码。考虑:

String someUrl=...;
Connect(someUrl);

  在这种情况下,第一个版本简单的传递someUrl的引用[译注:从非常量到常量是标准转型]。第二个版本会创建一个someUrl的副本,调用Connect,然后销毁那个副本。随着调用Connect的静态数量的增长,代码大小的开销同时增长。另一方面,例如Connect(MakeUrl())这样的调用会引入临时对象,在第二个版本中又刚好生成更少的代码。在多数情况下,大小差异好像不会导致问题产生[译注:在某些小内存应用中则是一个问题,例如嵌入式应用环境]。

  所以我们给出了一套不同的推荐规则:

  [规则1]如果函数内部总是制作参数的副本,按值传递。

  [规则2]如果函数从来不复制参数,按常量引用传递。

  [规则3]如果函数有时复制参数,而且关心效率,则按照Mojo协议。

  现在只留下开发Mojo协议了,不管它是什么。

  主要的想法是重载同样的函数(例如Connect),目的是辨别临时的和非临时的值。后者也称为左值(lvalue),因为历史原因,左值因为可以出现在赋值运算符的左边而得名。

  现在开始重载Connect,第一个想法是定义Connect(const String&)来捕捉常量对象。然而这是错误的,因为这个声明“吞吃”了所有的String对象,不管是左值(lvalue)或者临时对象[译注:前面提到过,非常量可以隐式转型为常量,这是标准转型动作]。所以第一个好主意是不要声明接受常量引用的参数,因为它像一个黑洞一样,吞噬所有的对象。

  第二个尝试是定义Connect(String&)试图捕获非常量的左值。这工作良好,特别是常量值和无名的临时对象不能被这个重载版本接受,这是一个好的起点。现在我们只剩下在常量对象和非常量临时对象之间作出区分了。

作者:Andrei Alexandrescu    责编:豆豆技术应用

正在加载评论...