关于对象生命历程的会话

2016-01-29 12:19 9 1 收藏

关于对象生命历程的会话,关于对象生命历程的会话

【 tulaoshi.com - C语言心得技巧 】

关于对象生命历程的会话
作者:Jim Hyslop 翻译:宋科
出处:C/C++ User Journal 2002 Dec

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)

(译者注:我从网上看到这篇文章的原文,非常喜欢作者的写作风格,于是就利用业余时间将它翻译出来,并贴到网上,希望大家可以从中受益,因为我没有和作者或者这篇文章的版权所有者联系以取得这篇文章的版权,所以这篇中译文的版权不应归我所有,而且我未从中获得任何利益!而且,我对原作者及其版权所有者的敬仰有如涛涛江水,所以我绝没有侵犯原作者的任何意图。当然,要说“利益”还是有的,就是我加深了如下C++的知识:只能被绑定到一个常量的、非易失的引用上,左值却没有这样的限制;函数返回的引用是左值。而且不管怎么说,如果一个对象的构造函数中引用了的临时对象,而对象在该构造函数构造结束时就消逝了的话,那么该对象就成了一个“野引用”了。如果我理解得有错的话,请一定告诉我一声,谢谢,kesongemini@vip.163.com。还有 Herb Sutter 先生的《more C++ Exceptional》中文版已经由华中科技大学出版社出版,小弟窃喜着买了一本,沈阳三好街的大松科技书店进新书的速度快得惊人,都是8折,不知道还有没有更便宜的地方:)

假日前不久的那几天,我就那么一次没有感觉到最后期限(deadline )的压力――我正在做的这个项目都已经按计划完成了。
我选择了最喜欢的消遣方式,撇掉了source repository(译者:源码智囊团?不懂,是一款分析源码的软件吗?)。我经常在研读别人代码时,学习一些他们的技巧(对我来说是新的),以及学习如何避免他们代码中的错误。

class T{public: T & ref() { return *this; }};void f( T & );int main(){ f( T().ref() );}
开始时,我没有理解ref()函数的重点,因此我删除了对它的调用――我认为下边这样的代码应该可以正常运行:
int main(){  f( T() );}
然而,当我编译时,编译器提示有个错误:将非常量引用绑定到一个临时对象。我轻拍着前额――当然了,这种绑定是不允许的。回想起第一次遇到这类错误的时候the Guru(译者:下文按领袖译)给我的解释。
她说道:“禁止这种绑定的一个原因是为了防止狡猾的bug,我的孩子,看看下面的情况”
class U{// ... 任何代码 ...};void takesAndModifiesU( U & u ){// 执行操作以修改u的状态}class V{public: operator U();};void g(){  V v; // ... takesAndModifiesU( v ); // ...}
“如果允许那种绑定,编译器将调用转换操作符operator(),创建一个临时的U类的对象。这个匿名的临时对象将被传递到takesAndModifiesU,被修改,接着在函数调用完成之后被丢弃。原来的对象v,不会被改变――这会让这段代码的作者困惑不解的。”
然而,我真的困惑了。我不能理解原来的语句f(T().ref());为何能能够编译――那不也是将一个非常量引用绑定到一个临时对象上了么?
“我的孩子,你必须学会多思考一步”,领袖(The Guru)的声音从我耳边传来,而不是记忆中,让我着实吃了一惊,“考虑一下左值和右值。神圣的标准(ISO C++ 吗?)告诉我们可以用形式为T()的显示的类型转化创建一个右值。一个右值只能被一个常量的、非易失(non-volatile)的引用绑定,但是一个左值没有这样的限制。而且,函数返回一个引用的话,那么返回值就是左值。因此,编译器能够将绑定ref()绑定到一个非常量引用。”
“这样呀,只有我调用某一个返回值是引用的函数,就可以了吧,”我回答道,“嗨――赋值操作符返回一个引用,因此我可以这样写吧f( T() = T() );不错吧!”我热情洋溢。“我能想到这个技巧的许多用处哟。”
“小心,我的孩子。这种不常见的技巧可能是很危险的,不可以轻易使用的。事实上,我至少可以想到一种情况:是关于对象生命的,这样的话可能会导致未定义的行为。”
“你是指...”我提示了一句。
“吃完午饭之后再说吧,”领袖平静地答道。我看见远处的几个同事正在准备去吃午饭。我一把抓起外套,加入了他们,接着,我们向当地的一家饭馆走去。
不知何故,午餐时我们一直控制着不去谈论关于购物的话题。讨论多集中于我们最感情趣的假日电影,比较《三十四号街的神谕》重拍前后的不同,还有Alistair Sim 和 Patrick Stewart 哪一个更加吝啬。(我选了Stewart。)鲍勃对我此举感到奇怪,然而――我认为他最喜欢的角色会是Grinch,但是他却非常喜欢《美丽人生》。
当我吃完午饭回去时,我心满意足。我坐在桌子前,开始集中精神考虑领袖一会儿会说些什么。最后,我努力地保持着清醒,并写下了如下代码:
class U{ T& t_;public: U( T & t ) : t_( t ) { } };{ // ... 一些域块 ... U u( (T() = T()) ); // ... }

当对象u完成构造时,临时对象的生命就终结了,对象u将成为

来源:http://www.tulaoshi.com/n/20160129/1485552.html

延伸阅读
标签: Web开发
这些文字都是我平时在查资料时,放在硬盘上的,现也找不到出处了,sorry [document对象] 该对象是window和frames对象的一个属性,是显示于窗口或框架内的一个文档。 属性 alinkColor 活动链接的颜色(ALINK) anchor 一个HTMI锚点,使用A NAME=标记创建(该属性本身也是一个对象) anchors array 列出文档锚点对象的数组(A NAME...
生命线有科学依据吗? 生命线是属于迷信的一种,也是有科学的根据。生命线,也叫本能线,它代表人的寿命、体质、活力、能力、精力、健康和疾病状况。标准的生命线,深刻、明晰、饱满无简断分叉,不超过中指中垂线。不能错误地以它长短粗细来论寿命之长短。若有叉纹、障碍线,提示有大病先兆。老中医也看病也是先看手掌,也就是看手相。其...
想在struts中返回一个对象的json数据,通过定义 代码如下: action name="getUserByName" class="com.action.UserManagerAction" method="getUserByName" result name="success" type="json" userInfo /result /action 结果返回的是整个action类的所有成员变量的json数据。要想返回userInfo对象的数据,需要将返回参数定义为root对象 代码...
关于XML:以对象模型为中心 ray.lea.haan@hotmail.com 许多应用开发都需要与 XML 打交道,一种常见的做法是从 XML 入手:不是分析现有的 XML 格式,就是设计一个新的 XML 格式,然后使用 DOM、SAX 之类的解析器把 XML 转化为应用对象,这种做法当然可行,然而我认为存在以下几个缺点: 如果不是使用已定义的 XML 格式,就...
标签: Java JAVA基础
  10.1 会话状态概述 HTTP协议的“无状态”(Stateless)特点带来了一系列的问题。特别是通过在线商店购物时,服务器不能顺利地记住以前的事务就成了严重的问题。它使得“购物篮”之类的应用很难实现:当我们把商品加入购物篮时,服务器如何才能知道篮子里原先有些什么?即使服务器保存了上下文信息,我们仍旧会在电子商务应用中遇...

经验教程

488

收藏

83
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部