从operator=中“自我赋值”看new的抛出异常
来源:互联网 发布:情趣睡衣淘宝买家秀 编辑:程序博客网 时间:2024/06/18 04:00
在Effective C++中看到这个问题时才发现以前写的代码完全没有注意过这个问题
“自我赋值”发生在对象被赋值给对象本身时,例如:
class Weight{...};...w=w;
虽然这看上去确实非常的蠢,但是谁也不能保证这不会发生,毕竟这是合法的,但是问题出来了,我们写的显示赋值函数一般是这样的,假设我们在类中使用了动态分配。
class Bitmap{...};class Weight{...private:Bitmap * _pb;};Weight & Weight::operatot=(const Weight & rhs){delete _pb;_pb=new Bitmap(rhs._pb);return *this;}
好的,现在面临的问题是,*this和rhs这两个指向了同一个对象,在执行delete _pb 时同时也将rhs的Bitmap销毁了。
对此提出了两种有效的解决方法
①传统做法在operator=之前做一个“证同测试(identity test)”
Weight & Weight::operatot=(const Weight & rhs){if(this == &rhs) return *this;delete _pb;_pb=new Bitmap(rhs._pb);return *this;}
这样做完全行得通,但是为一件很少发生的事情花费额外的判断操作似乎不是很划算。
②依靠精心周到的语句顺序解决
调整最初的源代码
Weight & Weight::operatot=(const Weight & rhs){Bitmap *pOrig=_pb; //记住原先的_pb_pb=new Bitmap(rhs._pb); //令_pb指向*_pb的一个副本delete pOrig; //删除原先的_pbreturn *this;}
再调整顺序后,在重新new之后再摧毁原来的_pb,这样的操作具有很高的异常安全性。这里有一个问题,如果new失败了怎么办?
我相信所有人一定都写过这样一段代码
int *p=new int[5];if(p==NULL) return -1;
当我们使用malloc/calloc分配内存时,检测返回值是否为”空指针”是一个良好的习惯,可惜的是new在默认状态下,分配失败并不会返回一个空指针,而是抛出(throw)一个异常!!
对此正确的操作有如下两个方法:
①捕获异常
try{ _pb=new Bitmap(rhs._pb); ... //其他操作}catch(const bad_alloc& e ){ return -1;}
②标准 C++ 亦提供了一个方法来抑制 new 抛出异常,而返回空指针
int* p = new (std::nothrow) int; // 这样如果 new 失败了,就不会抛出异常,而是返回空指针 if ( p == 0 ) // 如此这般,这个判断就有意义了 return -1; ... // 其它代码 delete p;
0 0
- 从operator=中“自我赋值”看new的抛出异常
- operator new抛出异常的处理
- 在operator=中处理自我赋值
- 关于operator=的自我赋值问题
- [effectiv c++]条款11:operator=的自我赋值与异常处理
- operator=处理自我赋值
- 条款11: 在operator= 中处理"自我赋值"
- 条款11:在operator= 中处理“自我赋值”
- 条款11: 在operator= 中处理"自我赋值"
- item11: 在operator=中处理自我赋值
- 条款11:在operator = 中处理"自我赋值"
- 条款11:在operator=中处理“自我赋值”
- tip11:在operator=中处理自我赋值
- 条款11:在operator=中处理”自我赋值“
- 总结条款:11在operator=中处理“自我赋值”
- 第11条: 在 operator= 中处理“自我赋值”
- 条款11 在operator=中处理“自我赋值”
- 条款11:在operator=中处理“自我赋值”
- fatal error C1001: INTERNAL COMPILER ERROR VC6.0BUG
- ie6、7下inline-block
- Android ListView点击事件无反应
- VS2013_Qt5打包—发布
- 传值、传指针、传引用
- 从operator=中“自我赋值”看new的抛出异常
- hdoj 1505 City Game 【dp or 单调栈】
- js prototype
- WEB开发的套路——数据流向的套路
- POJ 3254 状压dp
- 配置Ubuntu的tftp服务
- 安卓中通过intent组件跳转到系统联系人编辑界面,及具体案例分析
- POJ 1128 Frame Stacking
- LeetCode Single Number