TITLE: don't use placement new in assignment operators (Source: comp.lang.c++.moderated, 12 Dec 2000) NIESSEN: Peter Niessen >>> If the assignment operator looks like >>> >>> MyClass MyClass::operator = (const MyClass &other) { >>> ~MyClass(); >>> new (this) MyClass(other); >>> return *this; >>> } >>> >>> then it shouldn't. That approach isn't exception safe, and it >>> messes with the notion of object lifetimes in a way which is >>> likely to make Herb Sutter feel unwell if he reads this post. SUTTER: Herb Sutter Since you single me out, I suppose it's likely because of either my November 2000 CUJ column, or Item 41 in Exceptional C++ which is devoted entirely to debunking this anti-idiom. If you haven't read Item 41 yet, please do. As I point out in that Item, this approach has lots of problems, especially as written above: 1. As commonly implemented, it can slice objects. 2. It's not exception-safe (as you noted). 3. It plays havoc with normal object lifetimes (as you noted). 4. It makes life hellish for derived classes. 5. As written above, it's not safe for self-assignment; the self-assignment test is mandatory (and, alas, insufficient because of the other problems). In the end, the main point Item 41 makes is that it's indeed okay to implement copy assignment in terms of copy construction -- but this anti-idiom is NOT the way to do it. Instead, used the common true idiom: T& T::operator=( const T& other ) { T temp( other ); Swap( temp ); // Swap is a nothrow function return *this; } See Item 41 for details and discussion. Interestingly, a few people have told me that they felt I spent too much space protesting this anti-idiom when it's clearly wrong and not worth the thorough spanking I give it; my response to them has been that it's needed because the anti-idiom keeps cropping up in the newsgroups. :-) Don't feel bad, though, you're not alone and even some experts encouraged it in the early days. Sometime later, James Kanze responded in part: >This idiom will cause problems if the copy constructor throws. It >isn't thread-safe (but then, operator= often isn't). Most of all, if >someone derives from MyClass and doesn't use it, the results will >probably be undefined behavior of the worst sort. > >But other than that, it works. Well, I like the way you put that, because such heavily-caveated "damning with faint praise" speaks volumes. :-) Even so, I really really recommend against even such slight encouragement of this anti-idiom. It's fragile and fraught with peril. For example, you're an expert and you're experienced with this idiom too boot, yet even you say "other than [some major problems] it works," and I think missed that as presented above it's not even safe for self-assignment -- that's how easy it is for mistakes to slip through once we're off in the weeds of such fragile constructs. >In the end, Scott Meyers convinced me that I was >wrong about this. I stopped recommending it because closed >hierarchies generally end up becoming open. I'm with Scott on this one, and I recommend against it for way more reasons than just problems related to derived classes (which speaks only to problems 1 and 4 above). _______________________________________________ cpptips mailing list http://cpptips.hyperformix.com