分享
 
 
 

Herb Sutter的对话#30:It's an Object-ful Lifetime

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

对话#30:It's an Object-ful Lifetime(WQ译)

那是在假日的前几天。难得一次, 没有截止期限的压迫—我所从事的项目都已经按时完成了。

我经常在源码库中闲逛以作为消遣。当研究其他程序员的代码时,我时常学到新的技巧—以及应该避免的技巧。 我偶然发现了一个有趣的东西,它被浓缩在下面的小程序中:

class T

{

public:

T & ref(){ return *this;}

};

void f(T &);

int main()

{

f(T().ref());

}

起先 ,我没了解ref()函数的意图,因此我移除了对它的调用—我预料它应该能够工作:

int main()

{

f(T());

}

然而,当我编译它时,编译器提示有一个错误一在临时对象上绑定了一个非const的引用。 我拍了一下脑袋—这当然是不允许的!我回想起Guru的讲解,就在我第一次碰到这个问题的时候。

" 此禁令的一个理由是要避免一些微妙的bug,"她曾经说过。"我的孩子 , 考虑下列情况:"

class U

{

//...whatever...

};

void takesAndModifiesU( U & u)

{

// performs actions that modify the state of u

}

class V

{

public:

operator U();

};

void g()

{

V v;

//...

takesAndModifiesU;( v)

//...

}

"如果绑定被允许,编译器会调用类型转换操作,构造一个临时的U对象。然后这个无名的临时对象将被传给takesAndModifiesU并被修改,然后在函数调用完成后被丢弃。最初的对象v,根本就没有被动过-这将给写这个函数的人以极大的困扰。"

但是,我还是被困扰了。我不明白最初的f(T().ref());语句怎么可以编译的—它还是在一个临时对象上绑定了一个非const的引用啊。

"你不能局限在不变性上,我的孩子,"Guru声音震惊了我—来自于真实世界的,而不是记忆中的。"转而想一下lvalue和rvalue。神圣的标准告诉我们T()形式的一个显式类型转换产生一个rvalue。 rvalue只能绑定到一个const的引用,而lvalue没有这个限制。另一方面,返回引用的函数,其结果是得到一个lvalue[1]. 因此编译器能将非const的引用绑定在ref()的结果上。"

"于是,只要我调用一个返回引用的函数就没问题了,"我答道。 " 嗨—赋值运算符返回引用,因此我可以写 f(T() = T());。多妙!"我来劲了。 "我能想出这个技巧有很多用途"。

"小心,我的孩子。 如此不寻常的技巧是危险的,不应该轻易使用。 的确,我认为至少有一问题,关于对象生命期的,会导致未定义行为。"

" 那个是..." 我催促道。

" 先自己想,午饭之后吧,"Guru缓缓答道。在远处,我看见一些同事已经准备去吃部门的假日聚餐了。我抓起外套,加入了他们,前往附近的一家饭店。

不知何故,我们实际上设法避免在吃饭时讨论购物。 讨论集中在我们喜爱的假日电影上,comparing the various remakes of Miracle on 34th Street, and whether Alistair Sim or Patrick Stewart made a better Scrooge。 (My vote was for Stewart。) Bob surprised me, though — I figured his favorite character would be the Grinch, but instead he waxed poetic on It's A Wonderful Life.(WQ注:Sorry,由于和技术无关,而又实在译不好,所以没译。)

当我们吃完饭回来,我感觉很好。我在桌前坐下并开始沉思Guru所指的是什么。 最后,当我努力保持眼睛睁开时,我明白了:

class U

{

T & t_;

public:

U( T & t) : t_( t ) {}

};

{//... some block scope ...

U u( (T() = T()) );

//...

}

一旦u对象完成构造,临时对象的生命期就结束了,而u对象会带着一个悬挂引用被留了下来。

就好象T对象从来没有存在过,我陷入沉思中。

"好的,George,"我听到了Guru的声音,"你已经得到了你的愿望。你从来就没有出生过。"

"嗯? George是谁?"我转向Guru。

"当然是你,"Guru答道。我一看到她,就认识到我正在做梦—那种你明知道是梦,但走到哪里都跟着你的梦。"你是George Bailey。 你构造的对象从来没有存在过。我的工作就是向你说明当涉及未定义行为时会发生什么。"

在远处,我看到一个条幅:"欢迎来到Bobville。"

"Bobville?" 我问,畏惧于这个名字。

"城镇是由你的死对头Bob控制,"Guru说道。 "他也是银行的拥有者 , 和软件开发部的头儿。让我们沿主要街道散步一下。"

当我们向前走的时候,我看见了不能言状的惊骇—没有分隔的整块代码,被命名为i和j的变量,和"NULL指针的反引用于此"的商业广告牌。在一个街道拐角上,我看见了一些程序员正毫无愧色地拷贝-粘贴代码。

我看见Kerry驾驶正驾驶着一辆出租汽车。我示意他停下来。

"把我带离这里,Kerry," 我在钻入车厢时喊道。 "把我带回办公室,那个我们写出理性代码的地方"。

"Kerry?我的名字是Ernie(摇奖机)。 我不懂写代码; 我只是开出租车的。"我们从Wendy旁驶过,她穿着警服。Kerry挥手向她示意。知道它是一个梦,而我没有被设定为注意他的行动,我忽略了他。

我们在一栋废弃的办公大楼前停下。 我跳出车跑进去。我找到了一块白板,它上面有一些不爽的代码,于是重写了它:

{//... some block scope ...

T tmp;

U u( tmp );

}

就在我放下书写笔时,我被惊醒了。

"哇 !" 我自言自语着,一边去餐厅拿我能找到的最浓的咖啡。

注:

[1] ISO/IEC 14882:1998(E), "International Standard, Programming Languages — C++", clauses 5.2.3, 8.5.3, and 3.10 respectively.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有