Effective C++ 笔记 —— Item 11: Handle assignment to self in operator=.
2021/8/31 11:06:06
本文主要是介绍Effective C++ 笔记 —— Item 11: Handle assignment to self in operator=.,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
An assignment to self occurs when an object is assigned to itself:
class Widget { ... }; Widget w; //... w = w; // assignment to self
If you try to manage resources yourself, however (which you’d certainly have to do if you were writing a resourcemanaging class), you can fall into the trap of accidentally releasing a resource before you’re done using it.
class Bitmap { //... }; class Widget { //... private: Bitmap *pb; // ptr to a heap-allocated object }; Widget& Widget::operator=(const Widget& rhs) // unsafe impl. of operator= { delete pb; // stop using current bitmap pb = new Bitmap(*rhs.pb); // start using a copy of rhs’s bitmap return *this; // see Item 10 }
The self-assignment problem here is that inside operator=, *this (the target of the assignment) and rhs could be the same object. When they are, the delete not only destroys the bitmap for the current object, it destroys the bitmap for rhs, too. At the end of the function, the Widget — which should not have been changed by the assignment to self — finds itself holding a pointer to a deleted object!
The traditional way to prevent this error is to check for assignment to self via an identity test at the top of operator=:
Widget& Widget::operator=(const Widget& rhs) { if (this == &rhs) return *this; // identity test: if a self-assignment, // do nothing delete pb; pb = new Bitmap(*rhs.pb); return *this; }
This works, but it was also exception-unsafe, and this version continues to have exception trouble.
Happily, making operator= exception-safe typically renders it selfassignment-safe, too.
For example, we just have to be careful not to delete pb until after we’ve copied what it points to:
Widget& Widget::operator=(const Widget& rhs) { Bitmap *pOrig = pb; // remember original pb pb = new Bitmap(*rhs.pb); // point pb to a copy of rhs’s bitmap delete pOrig; // delete the original pb return *this; }
If we take advantage of the facts:
- a class’s copy assignment operator may be declared to take its argument by value.
- passing something by value makes a copy of it.
class Widget { //... void swap(Widget& rhs); // exchange *this’s and rhs’s data; ... // see Item 29 for details }; Widget& Widget::operator=(Widget rhs) // rhs is a copy of the object passed in — note pass by val { swap(rhs); // swap *this’s data with the copy’s return *this; }
This approach sacrifices clarity at the altar of cleverness, but by moving the copying operation from the body of the function to construction of the parameter, it’s a fact that compilers can sometimes generate more efficient code.
Things to Remember
- Make sure operator= is well-behaved when an object is assigned to itself. Techniques include comparing addresses of source and target objects, careful statement ordering, and copy-and-swap.
- Make sure that any function operating on more than one object behaves correctly if two or more of the objects are the same.
这篇关于Effective C++ 笔记 —— Item 11: Handle assignment to self in operator=.的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享