C++Reference 的“三位一体”诠释

发表于:2014-9-01 10:20

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:杨镰    来源:51Testing软件测试网采编

  C++ 是介于汇编语言与高级语言之间的一种“全能”语言。它的能力是其他任何基于VMA(冯-诺曼架构)计算机的高级程序设计语言无法望其项背的,而性能也只有C语言可与之伯仲。
  然而长期以来,喜欢C++和憎恨C++的阵营,恶斗了三十多年,谁也说服不了谁。其中的一个重要原因是:C++的逻辑和语意难以分割,计算机学术界很难把它形式化(比如具有像Haskell那样的数学美), 这和量子力学里的不确定性类似,爱因斯坦就对此讨厌之极。
  这里我不想评论两方的对错,但是我想就C++的一个最基本的概念,也是最重要的概念之一的“reference",作一番论述,看看是否说得通。
  读者如果读过拙文“ http://blog.csdn.net/ly8838/article/details/38638491”,可能会对reference微妙的一面有所共鸣的。这里我想进一步谈谈reference的一些细节。
  要想叙述reference,我们不得不从更基本的定义 - 直接对象(direct object)说起.
  C++中,直接对象是“常规变量”(normal variable), 具有“值语意”(value semantics),和rvalue 语意。 这还没有引入reference,就已经陷入逻辑上“循环定义”的怪圈了。要想跳出,只有举例:
  long x;
  MyClass m;  // MyClass is a user defined class
  上面x和m都是“直接变量”,它们在内存中的区域可以不同:可以在程序的静态空间(全程变量),可以在工作堆栈内(自动变量),也可在动态空间内(间接地包含在母object中)。由于所在区域不同,这些直接变量对程序性能的特征影响很大(以后的博克会提及)。但是最重要的,是它们和传统的“基本型变量(primitive type variable)”在语法和用法上的相似。这是C++为何会支持它的重要原因。
  对于首先学习C#,JavaScript, 或其他现代语言的程序员来说,“直接变量”几乎没有对应的概念。而更加令人不解的是,在“动态空间(heap)”中,直接变量只能“间接”地存在。而能够“直接使用”动态变量"的唯一方法只有“指针”和“reference”. 这里又陷入了循环:解释直接变量时,又无法绕开“指针”和“reference”。
  那么reference到底是什么呢?看看微基的解释,(http://en.wikipedia.org/wiki/Reference_(C%2B%2B)),它几乎也是同意反复,最后只有用“比喻”来解释。也就是说,不用“指针”,“内存地址”等概念就无法解释。
  那么,通俗上的说法“reference 是变量的alias (同体异名?)”是否说得通呢?
  我认为,对于初学者来说,alias可谓最好的“比喻”。请看:
  int x = int(10);           // line1
  int & r = x;                // line2: r is an alias of x
  r++;                         // line3: x is now 11
  r = 3;                       // line4: x is now 3
  assert (&r == &x);     // line5: r points to x
  我们看到,上面的程序显示,r 和 x 几乎没任何区别,好像是形影相随,难分难舍。这正是C++的宗旨:让reference的变量和直接变量具有“等同”的语法,用法。
  作为初级程序员来说,知道到这个用法也就够了,但是“一点点知识是危险的”。如果我们以为x 和 r 是一个东西,那就错了:
  首先,x 是“直接变量”,而r是间接变量,所以它们在语意上是完全不一样的(编译出来的代码大相庭径)。你可以说这与我无关,会应用就行了,这也不错,不过并不能高枕无忧:在另一个环境里,你可能就会因为不清楚object reference 和 direct object 的区别而出错,或是写出性能差别极大的程序。
  从语意上看,line2 几乎等于 r = &x (取x的地址),无怪乎许多人认为 reference 其实就是指针, 而且line5证明它的确指着它的“直接变量”。知道这一点,对于下列代码很重要:
  class X {…}
  void myXFunction(X x) {…}
  void myXFunction2(const X & x) {…}
  如果认为X& 是 X 的“alias”,而且用法一样, 那么你可能不需要myXFunction2,但是如果你知道X&的语意和X * 一样,你才会推论出myXFunction2的性能一般会比myXFunction好,特别是当X里面包含大量“成员”时,myXFunction2不用copy 内容,只需copy地址 (我们说这是浅拷贝- shallow copy), 而myXFunction必须传入的内容copy 到argument变量中(我们说这是深拷贝- deep copy)。
  在这里,语意盖过了逻辑。const X &x 的用法,特别是语意,最好用指针来诠释才说得过去。
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号