C++ Tutorial
Operator Overloading II
self assignment - 2020
Why do we need to protect against the self assignment when we do overloading assignment operator?
But before we dig into the reason why, who would do that kind of silly self assignment?
Window w; w = w; // nobody will do this w[i] = w[j]; // this may happen
Anything can happen. When we write a code, we're not supposed to do make any assumption. So, we need to guard against it.
Here is the code without any protection.
class ScrollBar {}; class Window { ScrollBar *sb; public: Window(ScrollBar *s) : sb(s) {} Window() = default; Window& operator=(const Window&); }; Window& Window::operator=(const Window& rhs) { delete sb; sb = new ScrollBar(*rhs.sb); return *this; } int main() { Window w(new ScrollBar); Window w2(w); }
The code shows a typical overloading assignment overloading.
What could be the flaws in the code?
What could happen if *this and rhs is the same Window instance?
If that's the case, the following line is the problem:
delete sb;
We're deleting rhs.sb since *this and rhs are the same object. After deleting the sb, we're trying to access already deleted object of rhs:
sb = new ScrollBar(*rhs.sb);
We do not want to that happen. The immediate solution is this:
if (this == &rhs;) return *this; delete sb; sb = new ScrollBar(*rhs.sb); return *this;
Still there is a problem.
What if an exception is thrown in the copy constructor after we deleted sb. Then, we're end up having a pointer which is pointing to nothing. So, we need a better code:
Window& Window::operator=(const Window& rhs) { if (this == &rhs;) return *this; ScrollBar *sbOld = sb; sb = new ScrollBar(*rhs.sb); delete sbOld; return *this; }
In this way, the Window object can still holding the ScrollBar even in when there is a thrown exception.
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization