分享
 
 
 

C++ FAQ Lite[12]--赋值算符(新)

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

[12] 赋值算符

(Part of C++ FAQ Lite, ]Copyright © 1991-2001, Marshall Cline, cline@parashift.com)

简体中文版翻译:申旻nicrosoft@sunistudio.com东日制作室东日文档

FAQs in section [12]:

][12.1] 什么是“自赋值”?

][12.2] 为什么应该当心“自赋值”?

][12.3] 好,好;我会处理自赋值的。但如何做呢?

[12.1] 什么是“自赋值”?

自赋值就是将对象赋值给本身。例如,

#include "Fred.hpp" // 声明 Fred 类

void userCode(Fred& x)

{

x = x; // 自赋值

}

很明显,以上代码进行了显式的自赋值。但既然多个指针或引用可以指向相同对象(别名),那么进行了自赋值而不知道的情况也是可能的:

#include "Fred.hpp" // 声明 Fred 类

void userCode(Fred& x, Fred& y)

{

x = y; // 如果&x == &y就可能是自赋值

}

int main()

{

Fred z;

userCode(z, z);

}

[ Top | Bottom | Previous section | Next section ]

[12.2] 为什么应该当心“自赋值”?

如果不注意]自赋值,将会使你的用户遭受非常微妙的并且一般来说非常严重的bug。例如,如下的类在自赋值的情况下将导致灾难:

class Wilma { };

class Fred {

public:

Fred() : p_(new Wilma()) { }

Fred(const Fred& f) : p_(new Wilma(*f.p_)) { }

~Fred() { delete p_; }

Fred& operator= (const Fred& f)

{

// 差劲的代码:没有处理自赋值!

delete p_; // Line #1

p_ = new Wilma(*f.p_); // Line #2

return *this;

}

private:

Wilma* p_;

};

如果有人将 Fred 对象赋给其本身,由于*this和 f 是同一个对象,line #1同时删除了this->p_和f.p_。而 line #2使用了已经不存在的对象*f.p_,这样很可能导致严重的灾难。

作为 Fred 类的作者,你最起码有责任]确信在Fred对象上自赋值是无害的。不要假设用户不会在对象上这样做。如果对象由于自赋值而崩溃,那是你的过失。

另外:上述的Fred::operator= (const Fred&)还有第二个问题:如果在执行new Wilma(*f.p_)时,抛出了异常(例如,]内存不够的异常或者]Wilma的拷贝构造函数中的异常), this->p_将成为悬空指针——它所指向的内存不再是可用的。这可以通过在删除就对象前创建对象来解决。

[ Top | Bottom | Previous section | Next section ]

[12.3] 好,好;我会处理自赋值的。但如何做呢?

[Recently reworded the last paragraph (on 7/00). ]Click here to go to the next FAQ in the "chain" of recent changes.]

]在你创建类的每时每刻,都应该当心自赋值。这并不意味着需要为你所有的类都增加额外的代码:只要对象优美地处理自赋值,而不管是否必须增加额外的代码。

如果不需要为赋值算符增加额外代码,这里有一个简单而有效的技巧:

Fred& Fred::operator= (const Fred& f)

{

if (this == &f) return *this; // 优美地处理]自赋值

// 此处写正常赋值的代码...

return *this;

}

显式的测试并不总是必要的。例如,如果修正]前一个 FAQ中的赋值算符使之]处理new抛出的异常和/或Wilma类的]拷贝构造函数抛出的异常,可能会写出如下的代码。注意这段代码有(令人高兴的)自动处理自赋值的附带效果:

Fred& Fred::operator= (const Fred& f)

{

// 这段代码优美地(但隐含的)处理]自赋值

Wilma* tmp = new Wilma(*f.p_); // 如果异常在此处被抛出也没有问题

delete p_;

p_ = tmp;

return *this;

}

在象这个例子的情况下(自赋值是无害的但是低效),一些程序员想通过增加另外的不必要的测试,如“if (this == &f) return *this;”来改善自赋值时的效率。通常来说,使自赋值情况更高效而使得非自赋值情况更低效的折衷是错误的。例如,为Fred类的赋值算符增加如上的if测试会使得非自赋值情况更低效(一个额外的(而且不必要的)条件分支)。如果自赋值实际上一千次才发生一次,那么 if 将浪费99.9%的时间周期。

[ Top | Bottom | Previous section | Next section ]

E-mail the author

[ C++ FAQ Lite | Table of contents | Subject index | ]About the author | | ]Download your own copy ]

Revised Apr 8, 2001

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