Go Back   Rhinocerus > Newsgroup > Newsgroup comp.language.c++ > Newsgroup comp.language.c++.moderated

Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old 12-09-2009, 10:04 PM
muler
Guest
 
Posts: n/a
Default calling this->~T() inside T::operator=

Consider this:

T& T:perator=(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! ]

Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #2 (permalink)  
Old 12-10-2009, 10:32 AM
Chris Uzdavinis
Guest
 
Posts: n/a
Default Re: calling this->~T() inside T::operator=

On Dec 9, 5:04 pm, muler <mulugeta.abe...@gmail.com> wrote:
> Consider this:
>
> T& T:perator=(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! ]

Reply With Quote
  #3 (permalink)  
Old 12-10-2009, 10:32 AM
Goran
Guest
 
Posts: n/a
Default Re: calling this->~T() inside T::operator=

On Dec 10, 12:04 am, muler <mulugeta.abe...@gmail.com> wrote:
> Consider this:
>
> T& T:perator=(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! ]

Reply With Quote
  #4 (permalink)  
Old 12-10-2009, 12:40 PM
Taras Shevchuk
Guest
 
Posts: n/a
Default Re: calling this->~T() inside T::operator=

On 10.12.2009 1:04, muler wrote:
> Consider this:
>
> T& T:perator=(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:perator=(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! ]

Reply With Quote
  #5 (permalink)  
Old 12-10-2009, 12:41 PM
Mathias Gaunard
Guest
 
Posts: n/a
Default Re: calling this->~T() inside T::operator=

On 9 déc, 23:04, muler <mulugeta.abe...@gmail.com> wrote:
> Consider this:
>
> T& T:perator=(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:perator=(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! ]

Reply With Quote
  #6 (permalink)  
Old 12-12-2009, 09:12 AM
Mathias Gaunard
Guest
 
Posts: n/a
Default Re: calling this->~T() inside T::operator=3D

On 10 d=E9c, 11:32, Goran <goran.pu...@gmail.com> wrote:

> Destructor should almost never be called explicitly.


It is perfectly fine to call it yourself, you just have to be aware
you need to provide a fallback solution in case of exceptions. Usage
of nothrow default constructor or move constructors can be quite
helpful, for example.


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

Reply With Quote
  #7 (permalink)  
Old 12-12-2009, 09:12 AM
Mathias Gaunard
Guest
 
Posts: n/a
Default Re: calling this->~T() inside T::operator=3D

On 10 d=E9c, 13:40, Taras Shevchuk <sh...@gala.net> wrote:

> 2. in case if T is base class then "this->~T();" will partially delete
> object.


Not if the destructor is virtual.


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

Reply With Quote
  #8 (permalink)  
Old 12-13-2009, 08:29 AM
Goran
Guest
 
Posts: n/a
Default Re: calling this->~T() inside T::operator=3D

On Dec 12, 11:12 am, Mathias Gaunard <loufo...@gmail.com> wrote:
> On 10 d=E9c, 11:32, Goran <goran.pu...@gmail.com> wrote:
>
> > Destructor should almost never be called explicitly.

>
> It is perfectly fine to call it yourself, you just have to be aware
> you need to provide a fallback solution in case of exceptions. Usage
> of nothrow default constructor or move constructors can be quite
> helpful, for example.


Of course var.~TYPE() can be made to work, I never tried to say that.
My point was that there is almost no reason to do it. I showed some
reasons, and of course tried to dismantled them ;-).

I was more going with this: "you just need..." part is scary,
especially if asked by someone with less experience and/or
understanding of the issues.

Goran.


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

Reply With Quote
  #9 (permalink)  
Old 12-13-2009, 02:31 PM
Mathias Gaunard
Guest
 
Posts: n/a
Default Re: calling this->~T() inside T::operator=3D

On 13 déc, 09:29, Goran <goran.pu...@gmail.com> wrote:

> Of course var.~TYPE() can be made to work, I never tried to say that.
> My point was that there is almost no reason to do it. I showed some
> reasons, and of course tried to dismantled them ;-).


Here is a good reason: you want to use a specific part of memory to
store objects of different types.
boost::variant, for example.


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

Reply With Quote
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Calling C or C++ Functions inside Python script Pablo Torres N. Newsgroup comp.lang.python 0 07-04-2009 01:25 PM
Re: Calling C or C++ Functions inside Python script Chris Rebert Newsgroup comp.lang.python 0 07-04-2009 10:29 AM
Re: Need advice on using a macro inside a data step array loop Jim Groeneveld Newsgroup comp.soft-sys.sas 0 06-13-2006 01:20 PM
Re: How to realize a nested cycle-program? toby dunn Newsgroup comp.soft-sys.sas 0 07-05-2005 09:48 PM
Re: accesing a variable from calling data statement inside acalled macro Schwarz, Barry A Newsgroup comp.soft-sys.sas 0 10-25-2004 10:49 AM



All times are GMT. The time now is 06:15 PM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.