|
|||
|
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! ] |
|
|
||||
|
||||
|
|
|
|||
|
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.htmSummary: 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! ] |
|
|||
|
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! ] |
|
|||
|
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! ] |
|
|||
|
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! ] |
|
|||
|
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! ] |
|
|||
|
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! ] |
|
|||
|
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! ] |
|
|||
|
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! ] |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|
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 |