C++的自赋值问题
来源:互联网 发布:淘宝一般包邮地区 编辑:程序博客网 时间:2023/09/26 10:46
再用到操作符重载的时候,注意到了这个问题
如果不进行自我赋值检查。就有可能出现一种情况。那是灾难性的。举例说。你在拆房子。如果你不先看看自己是否在房子里就直接拆了。那会是怎么样呢??想想就知道。
在网上搜索了一下,转载一个现成的:http://www.lough.com.cn/cpp/thincpp2.htm
1.需要考虑的自赋值。当类包含指针或引用成员时应注意检查。
class String
{
private:
char * pc_Buffer;
public:
String & operator=(const String & strR);
String & operator+=(const String & strR);
//...
};
(1)类内部:对称赋值运算符、接受自身类型或自身基类类型参数的成员
函数,有时候还要考虑+=系列运算符。
String & String::operator=(const String & strR)
{
if (this==&strR) //[1]
return *this;
delete [] pc_Buffer; //[2]
pc_Buffer=new char[strlen(strR.pc_Buffer)+1];//[3]
//...
}
[1] 中的判断是必须的。如果this==&strR ,[2] 将本身删除,[3] 就会使
用“悬挂指针”。
下面operator+=()的实现隐藏着错误。
String & String::operator+=(const String & strR)
{
int iLengthNew=strlen(pc_Buffer)+strlen(strR.pc_Buffer);
char * pcBufferNew=new char[iLengthNew+1];
strcpy(pcBufferNew,pc_Buffer);
delete [] pc_Buffer; //[4]
strcat(pcBufferNew,strR.pc_Buffer); //[5]
pc_Buffer=pcBufferNew;
return *this;
}
如果this==&strR ,[4] 将本身删除,[5] 就会使用“悬挂指针”。正确的
做法不必使用判断语句,只需调换[4][5]两条语句的顺序。
(2 )类外部(包括友元):接受多个同一类型参数或多个有继承关系的类
型参数的函数。
class CDerive : public CBase{};
void f(CBase & b1,CBase & b2);
void g(CBase & b,CDerive & d);
CBase bSame;
CDerive dSame;
f(bSame,bSame); //[1]
f(dSame,dSame); //[2]
g(dSame,dSame); //[3]
[1][2][3]都出现了自赋值,所以f()、g()的设计中都要有所考虑。
2.不可能出现自赋值。
(1 )拷贝构造器:因为正在构造的对象还未完全生成,而传递给构造器的
实参对象是已构造完毕的对象,这两者绝不可能是同一对象。
(2 )非对称赋值运算符:即使形参类型是自身的基类。若D 是B 的派生类,
无论是否重载了对称赋值运算符,D 类对象之间的赋值行为都不会调用
D::operator=(const B& b)。
class CDerive : public CBase
{
public:
operator=(const CBase & b); //不用考虑this和b之间的自赋值
void f(const CBase & b); //需要考虑this和b之间的自赋值
};
CDerive dSame;
dSame=dSame; //[1]
dSame.f(dSame); //[2]
语句[1] 中,编译器不会把dSame 上溯造型为CBase ,而是调用缺省或自定
义的D ::operator= (const D & d )。只有等式左边确为D ,右边确为B ,
才调用D ::operator= (const B & b ),这时不可能出现自赋值。相反,语
句[2] 中,编译器会把dSame 上溯造型为CBase ,所以f ()需要考虑自赋值。
3.不是自赋值的赋值。仅仅内容相同的赋值不是自赋值。
CTest a,b,same;
a=same;
b=same;
a=b; //[1]
[1] 不是自赋值,不会出问题,不需要检查,而且内容相同无法直接用地址
来检查。
4.不应该检查的自赋值。
strcpy(char * strDest,const char * strSrc );中,当strDest==strSrc
时,是自赋值,但并不会出错。
发现自赋值直接返回,这种特定情况下,也许能提高函数效率10倍,但绝大
多数没有出现自赋值时都多了一个条件判断,可能降低函数效率10% ,最后综合
计算加权平均效率可能还是降低了。这取决于自赋值出现的概率。
设不判断自赋值,函数执行时间为1 ;若检查自赋值,设出现自赋值的概率
为x ,直接返回函数执行时间为0.1 ,不出现自赋值,多了一个条件判断函数执
行时间为1.1 ,那么如果要求加权平均效率不降低:
0.1x+1.1(1-x)<1
解之,得:x>0.1.也就是说自赋值出现的概率必须大于10% ,这在实际代码
中可能吗?
- C++的自赋值问题
- [转]C++的自赋值问题
- C语言的位域赋值问题
- C语言指针的赋值问题
- 初学者的c普遍赋值问题
- C语言字符指针赋值的问题
- Item 11:赋值运算符的自赋值问题 Effective C++笔记
- 【C++】自我赋值问题
- Item 11 赋值函数的自赋值
- C语言自加自减的问题
- C语言变量赋值问题
- 关于c中对数组赋值的一个问题
- C语言字符数组的赋值问题及比较
- c中赋值类型匹配的一个小问题
- C/C++中赋值语句的返回值问题
- C常见问题之对结构变量的整体赋值问题
- C#——关于SqlParameter直接赋值的问题
- C/C++中赋值语句的返回值问题
- JAVA 泛型
- ie bug title 锚点
- POP3 SMTP 协议分析学习笔记
- HDU Bone Collector II 背包的K优解
- matlab画2d曲线命令
- C++的自赋值问题
- 查看内存泄露
- Quartz的任务的临时启动和暂停和恢复
- 第四周实验报告(二)
- 表单下拉选框及查询下拉选框
- 九度OJ 1184 二叉树递归创建遍历
- 第四周任务三:设计一个“正整数”类
- 四种强制转换类型运算符
- 第四周任务一