From: muler on
Consider this:

T& T::operator=(const T& other)
{
if(this != &other)
{
// the below code destroys *this, right?
// but are we not committing a suicide? -
// destroying *this inside (*this).operator= ??
this->~T();

new (this) T(other);
}
return *this;
}

Thanks!

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Chris Uzdavinis on
On Dec 9, 5:04 pm, muler <mulugeta.abe...(a)gmail.com> wrote:
> Consider this:
>
> T& T::operator=(const T& other)
> {
> if(this != &other)
> {
> // the below code destroys *this, right?
> // but are we not committing a suicide? -
> // destroying *this inside (*this).operator= ??
> this->~T();
>
> new (this) T(other);
> }
> return *this;
>
> }

This anti-pattern is covered at length in Herb Sutter's book
Exceptional C++, but the article of GotW is available online.
Please read it. :) http://www.gotw.ca/gotw/023.htm

Summary: bad! bad! bad! Don't do it! (And take a shower after
even thinking about it.)

Chris


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Goran on
On Dec 10, 12:04 am, muler <mulugeta.abe...(a)gmail.com> wrote:
> Consider this:
>
> T& T::operator=(const T& other)
> {
> if(this != &other)
> {
> // the below code destroys *this, right?
> // but are we not committing a suicide? -
> // destroying *this inside (*this).operator= ??
> this->~T();
>
> new (this) T(other);
> }
> return *this;
>
> }
>
> Thanks!
>

{ edits: quoted banner removed. please don't quote the banner. -mod }

This is 100% horrible code. This is code that would be written by
someone who understands C more or less well, but does not understand C+
+.

Yes, this is possible, and it's possible to work, but suffers from a
following problem: if constructor throws, this is not fully
constructed, but "reachable" (there are references to it in the code).
Depending on the situation, that might be more or less dangerous. Even
worse situation is if T has virtual methods and a base class, and a
base constructor throws - in usual implementations, that leaves T's
virtual table broken, which is a disaster waiting to happen.

Destructor should almost never be called explicitly.

Correct solution could be to tun things around and write copy
constructor in terms of operator=. Or to replace

this->~T();
new (this) T(other)

with a copy function and use that in both copy constructor and
assignment operator.

But none of that should be done unless performance profiling shows
that there's an issue in just having the most usual implementations (=
copies membes, copy ctor uses initialization list). Or if people
working on the code are just plain stupid and/or lazy and can't
remember, or be bothered, to keep two places in check.

Goran.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Mathias Gaunard on
On 9 d�c, 23:04, muler <mulugeta.abe...(a)gmail.com> wrote:
> Consider this:
>
> T& T::operator=(const T& other)
> {
> if(this != &other)
> {
> // the below code destroys *this, right?
> // but are we not committing a suicide? -
> // destroying *this inside (*this).operator= ??
> this->~T();
>
> new (this) T(other);
> }
> return *this;
>
> }

In any case, it's a bad idea since if new (this) T(other) throws,
you're screwed.

The recommended way to write operator= is

void T::swap(T& other)
{
using std::swap;
swap(member1, other.member1);
swap(member2, other.member2);
...
swap(memberN, other.memberN);
}

T& T::operator=(T other)
{
swap(other);
return *this;
}


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Taras Shevchuk on
On 10.12.2009 1:04, muler wrote:
> Consider this:
>
> T& T::operator=(const T& other)
> {
> if(this !=&other)
> {
> // the below code destroys *this, right?
> // but are we not committing a suicide? -
> // destroying *this inside (*this).operator= ??
> this->~T();
>
> new (this) T(other);
> }
> return *this;
> }
>
> Thanks!
>

I see following problems with your implementation:
1. object *this will be in inconsistent state in case if "new (this)
T(other);" generates exception;
2. in case if T is base class then "this->~T();" will partially delete
object.


The common pattern for assignment operation is following:
T& T::operator=(const T& other)
{
T tmp = other;
swap(tmp);
return *this;
}


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]