分享
 
 
 

Guru of the Week 条款11:对象等同(Object Identity)问题

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

GotW #11 Object Identity

著者:Herb Sutter

翻译:kingofark

[声明]:本文内容取自www.gotw.ca网站上的Guru of the Week栏目,其著作权归原著者本人所有。译者kingofark在未经原著者本人同意的情况下翻译本文。本翻译内容仅供自学和参考用,请所有阅读过本文的人不要擅自转载、传播本翻译内容;下载本翻译内容的人请在阅读浏览后,立即删除其备份。译者kingofark对违反上述两条原则的人不负任何责任。特此声明。

Revision 1.0

Guru of the Week 条款11:对象等同(Object Identity)问题

难度:5 / 10

(“我到底是谁?”这个问题蕴含着如何确定两个指针是否真的指向同一个对象的问题)

[问题]

测试语句“this != &other” 是一个防止自赋值(self-assingment)的常见编码手法。那么,要到达这个“防止自赋值(self-assingment)”目的,现有的语句是否是必要的和/或充分的呢?为什么?或者为什么不?如果答案是否定的,你又如何进行修改呢?注意要区分“protecting against Murphy vs. protecting against Machiavelli”。(* 译注:见本条款末尾)

T& T::operator=( const T& other ){

if( this != &other ) { // the test in question

// ...

}

return *this;

}

[解答]

一个简短的解答:从技术上来看,它既不是必要的也不是充分的。在实践当中,它工作得颇好但也有可能在C++标准中被修改。

* 论点:异常-安全(Murphy)

如果operator=()是异常-安全的(exception-safe),那么你并不需要检查自赋值(self-assignment)。这里有两个效率上的不利因素:a)如果可以进行自赋值(self-assignment)检查的话,那就可以进行彻底的优化从而省略掉赋值操作;b)如果代码被写成异常-安全的(exception-safe),那么同时也使得代码损失了一部分效率(这也即是说“paranoia has a price principle”,意即“偏执狂也有权衡代价的原则”)。

* 不是论点的论点:多重继承

过去曾有人把多重继承与本条款讨论的问题联系起来,但实际上这个问题与多重继承没有任何关系。我们的讨论的是一个涉及到C++标准怎样让你比较两个指针的技术性问题。

* 论点:运算符的重载(Machiavelli)

虽然一些类可能会提供它们自己的operator&(),但是问题中对自赋值(self-assignment)的检查却很可能不如你所期望的那样运作,而是做一些完全不同的事情。用“protecting against Machiavelli”来意寓这种情况是因为,我们只能推测编写operator=()的人也许大概知道他实现的类是不是也重载了operator&()。

要注意,一个类可能也会提供一个T::operator!=(),但这与本问题无关——它并不影响我们对自赋值(self-assignment)的检查,原因是:由于一个被重载的运算符至少有一个参数的类型必须是“类(class)”类型,因而我们不可能编写一个包含有两个T*型参数的T::operator!=()。

后记1

下面是一个所谓的“笑话代码(code joke)”。信不信由你,竟然真有一些并无恶意但无疑是被误导了的代码编写者曾企图使用这样的代码:

T::T( const T& other ) {

if( this != &other ) {

// ...

}

}

怎么样?你能第一眼就看出毛病吗?

后记2

值得注意的是,还有另外一些情况,在这些情况当中,指针的比较也不是多数人光凭直觉就能考虑周到的。比如:

1. James Kanze指出,把指针比较成字符串的行为是未定义的。其原因(我还未见有人给出过)是C++标准明确规定:允许编译器将字符串存放在重叠的内存区域以作为一种空间优化方案。

2. 一般来说,虽然像诸如<,<=,>和>=等内建(built-in)运算符的运算结果在各种特定情况下(比如,同一个数组中的两个指向对象的指针)都有着良好的定义,但你还是不能用这些运算符对任意的指针进行比较。标准库的使用也是基于这种限制的,其中规定:less<>以及其它库函数必须给出各指针的次序(ordering),以使得我们可以创建,比方说,一个key为指针类型的map,即map<T*,U,less<T*>>。(译注:此处的map是STL的一部分,一个map包括key和value两部分,使用的时候需要#include <map>)

(* 译注:关于Murphy和Machiavelli,侯捷先生在其系列书评的《C++/OOP大系》中提到:“就我的英文程度而言,[Sutter99](即《Exceptional C++》)读起来不若[Meyers96] (即《More Effective C++》)和[Meyers98] (即《Effective C++2/e》)那般平顺,原因是其中用了很多厘语、口语、典故。举个例子,Morphy law是什麽,大家知道吗?(莫菲定律说:会出错的,一定会出错。)Machiavelli又代表了什麽意思?(意大利政治家,以诈术闻名。)”

在这里,本条款的译者kingofark只能惭愧的说kingofark自己也没有完全理解本条款使用Murphy和Machiavelli两个词的用意。

Machiavelli:马基雅维利,尼克尔1469-1527意大利政治理论家,他的著作 君主论(1513年)阐述了一个意志坚定的统治者不顾道德观念的约束如何获得并保持其权力;马基雅弗利,意大利新兴资产阶级思想政治家,历史学家。)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有