社区
C++ 语言
帖子详情
不检测自赋值的危险???
renheihei
2004-08-30 03:21:25
为什么在重载operator=时需要检测自赋值情况呢?
书上说是不检测的话很危险,能不能举例子说明??
...全文
252
11
打赏
收藏
不检测自赋值的危险???
为什么在重载operator=时需要检测自赋值情况呢? 书上说是不检测的话很危险,能不能举例子说明??
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
11 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
insulator
2004-08-31
打赏
举报
回复
class String
{
public:
String(const char *str = NULL); // 普通构造函数
String(const String &other); // 拷贝构造函数
~ String(void); // 析构函数
String & operate =(const String &other); // 赋值函数
private:
char *m_data; // 用于保存字符串
};
String & String::operate =(const String &other)
{
// (1) 检查自赋值
if(this == &other)
return *this;
// (2) 释放原有的内存资源
delete [] m_data;
// (3)分配新的内存资源,并复制内容
int length = strlen(other.m_data);
m_data = new char[length+1]; // 若能加 NULL 判断则更好
strcpy(m_data, other.m_data);
// (4)返回本对象的引用
return *this;
}
Paris_Luo
2004-08-31
打赏
举报
回复
hehe,的确,少写了一句.
短歌如风
2004-08-31
打赏
举报
回复
Paris_Luo的意思是这样:
String::operator=(const String& src)
{
//不检查自赋值,一般代码如下,先释放,后拷贝
delete[] data;
data = new char[strlen(str.data) + 1];//Paris_Luo少写了这一句
memcpy(data,src,strlen(str.data)+1); //自赋值时,拷贝一块已释放的内存!!
return *this;
}
在自赋值发生的时候,代码中的data和str.data其实是同一个,那么在第二句中就访问了在第一句中已经释放了的内存(strlen(str.data),str.data已经释放),这种操作是很危险的。
不过即使没有自赋值的问题,这段代码也有问题:
在data = new char...时是可能产生异常的,然后对象中的data将指向一段没有释放的内存,这个对象已经不能正常工作,甚至不能正常析构。如果在delete[]data之后加一句data = NULL虽然可以解决这个问题,但仍然不好——这样只是保证了对象能使用而没有保证对象状态,一个好的赋值操作符应该在产生异常时保持对象状态与未赋值前一样。正确的实现应该是:
String::operator=(const String& src)
{
char * newdata = NULL;
if (str.data != NULL)
{
newdata = new char[strlen(str.data) + 1];
strcpy(newdata, str.data);
}
delete[] data;
data = newdata;
return *this;
}
这个实现大家可以看到:即使自赋值发生了,仍然不会有问题,只不过做了一些不必要的操作罢了。所以Pari_Luo这个例子并不能说明问题,它在解决了异常安全问题之后就不存在自赋值问题了。
晨星
2004-08-31
打赏
举报
回复
To:楼上
Paris_Luo(不懂)不是都给出例子了吗?
comebaby
2004-08-31
打赏
举报
回复
用new会有怎么样的问题?
能不能举个例子
DiabloWalkOnTheEarth
2004-08-30
打赏
举报
回复
呵呵,我也是,一般非对外的接口的类我都 assert , 不过其他的还是判断一下为好
短歌如风
2004-08-30
打赏
举报
回复
我一般不检查自赋值,因为我觉得自赋值是一种很可笑的行为,所以都:
assert(this != &source);
renheihei
2004-08-30
打赏
举报
回复
楼上能不能举个例子?谢谢
ra3
2004-08-30
打赏
举报
回复
主要是对象中有用 new 分配动态内存的情况。
这时不检查自赋值就会出错,如果不用 new 应该不会有什么问题。
DiabloWalkOnTheEarth
2004-08-30
打赏
举报
回复
没什么,偶尔coredump而已
Paris_Luo
2004-08-30
打赏
举报
回复
如果成员有指针,而且该指针在重载operator=时,先释放,再拷贝的话,在自赋值时,就会出现问题
例如
class String
{
public:
String(const char*);
String(const String&);
String& oprator=(const String&);
private:
char *data;
};
String::operator=(const String& src)
{
//不检查自赋值,一般代码如下,先释放,后拷贝
delete[] data;
memcpy(data,src,strlen(str.data)+1); //自赋值时,拷贝一块已释放的内存!!
return *this;
}
void main()
{
String str1("hello");
str1 = str1; //错误!
}
你必须知道的495个C语言问题
6.7 如果你不能给它
赋值
,那么数组如何能成为左值呢? 回顾 6.8 现实地讲,数组和指针的区别是什么? 6.9 有人跟我讲,数组不过是常指针。这样讲准确吗? 6.10 我还是很困惑。到底指针是一种数组,还是数组...
EasyUI应用(项目实战)
jquery入门基础,jquery
赋值
取值,事件处理和绑定,提交数据,datagrid控件显示数据,分页,事件处理;Tabs控件动态创建多标签;datebox日期时间控件的
赋值
和取值;window弹出窗口应用;tree创建树形菜单,部门列表...
【C++初阶】第五篇——类和对象(中)(构造函数+析构函数+拷贝构造函数+
赋值
操作符重载)
⭐️今天我要和大家分享C++中...
赋值
云运算符重载????运算符载????
赋值
运算符重载????与拷贝构造函数的异同????前置++和后置++的实现????const修饰类的成员函数????取地址及const取地址重载????总结 ????类的6个默认成
关于对象的自我
赋值
行为
所谓的自我
赋值
,指得就是一个对象
赋值
给...但既然我们提到自我
赋值
会引发问题,那我们先来澄清一下自我
赋值
的情况其实有时并不是那么显而易见的,并不一定都像上述代码那么愚蠢,它们还可能是这样:a[i] = a[j];*px...
C++ 语言
64,654
社区成员
250,484
社区内容
发帖
与我相关
我的任务
C++ 语言
C++ 语言相关问题讨论,技术干货分享,前沿动态等
复制链接
扫一扫
分享
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
请不要发布与C++技术无关的贴子
请不要发布与技术无关的招聘、广告的帖子
请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下
试试用AI创作助手写篇文章吧
+ 用AI写文章