delete this, Arrrrrgh!!

  • Thread starter n2xssvv g02gfr12930
  • Start date
N

n2xssvv g02gfr12930

In a job interview I was asked about the statement below:

delete this;

Naturally I was horrified, yet they claimed they had used it.
Personally I'm pretty damn sure I could never justify this. So
is this a case of Lord Bryon, "Mad, bad, and dangerous to know",
or do you think you could ever justify using it?

JB
 
J

Jim Langston

n2xssvv g02gfr12930 said:
In a job interview I was asked about the statement below:

delete this;

Naturally I was horrified, yet they claimed they had used it.
Personally I'm pretty damn sure I could never justify this. So
is this a case of Lord Bryon, "Mad, bad, and dangerous to know",
or do you think you could ever justify using it?

JB

Perhaps for some factory object. Or an object that only intended to be a
temporary or something.

Actually, if an object is on some list of pointers and it determines to
delete itself from the list, perhaps it could remove itself from the list
then delete itself.

I'm not sure if I'd ever do that though because it would throw off the list
iterators.

Hard to say. I'm sure somewhere someone has come up with a good reason to
use it, whether we agree with them or not.
 
A

Alf P. Steinbach

* n2xssvv g02gfr12930:
In a job interview I was asked about the statement below:

delete this;

Naturally I was horrified, yet they claimed they had used it.
Personally I'm pretty damn sure I could never justify this. So
is this a case of Lord Bryon, "Mad, bad, and dangerous to know",
or do you think you could ever justify using it?

It's common and practically necessary for e.g. objects that represent
windows in a graphical user interface. A different design choice is to
allow such objects to have a nullstate. That leads to an awful lot of
nullstate checking and in general a non-OO system architecture.
 
A

Alf P. Steinbach

* /Gogineni/:

Referring to a lot of dis-information by


* Anthony Langsworth, Mon, 2 Oct 2000:
Generally speaking, I'd recommend against using "delete this" in code. The
main problem is that the object can only be created via "new".

Which is not a problem.

If the object is declared "auto" (i.e. not a pointer or reference) and "delete
this" is called it will fail because "this" was not allocated with new and the
program will crash.

Which is not true: it's Undefined Behavior and there is no crash
guarantee.

If you really want to use "delete this" in your own code, make the destructor
protected,

Generally good advice.

preventing other classes from deleting the object and causing a compiler error if
an auto variable of this class is ever declared.

If you want to use in it a constructor, I'd recommend against it for the above reason

Which is meaningless or just false.

and also because the calling function has no way of knowing whether the object
encountered an error - calling one of the object's functions will result in a crash.

Which is false.

The object fails to instantiate itself will have to modify some form of global
variable such as errno, SetLastError(), IErrorInfo, etc, which, although acceptable,
is hardly ideal.

Which is an argument based on a false premise.

A much better way to report an error in an object's constructor is to use a static
"factory" function to encapsulate the construct. E.g.
static Dog* Dog::CreateDog(int legs) which can return a NULL pointer on an error.

Which is UnGood advice; generally an exception is preferable.

Alternatively, the constructor could throw an exception. Don't worry about memory
leaks, ANSI-compliant compilers should automatically deallocate the object with
calling the constructor [presumably he means: destructor] if a newed object throws
an exception in its constructor.

Which is false. Memory is reclaimed, the destructor isn't (and should
not be) called.

Check your compiler doco for this.
The only situation I've seen "delete this" where I consider it an acceptable use
is the the thread or window classes from MFC.

MFC is hardly an example of good OO design; it's often used as a
counter-example.

The intention with these classes is to instantiate them, remove all references to them
and let the objects manages their own lifespans.
I haven't got ARM (or a similar tome) handly but I suspect that modifying "this" in a
member funcion is illegal.

It is.

Either way, changing "this" in a member function will not affect the value of the
pointer the function was called through. E.g.
void zero_ptr(char* s)
{
// This line only changes the local version of s.
s = NULL;
}

char *s = "Hello, world!";

Using the deprecated conversion to char* (instead of char const*) is
abolutely not an example to follow.
 
N

n2xssvv g02gfr12930

Alf said:
* n2xssvv g02gfr12930:



It's common and practically necessary for e.g. objects that represent
windows in a graphical user interface. A different design choice is to
allow such objects to have a nullstate. That leads to an awful lot of
nullstate checking and in general a non-OO system architecture.
I'm still not happy destroying an object this way. Why not use a
static function passing the pointer and waiting for a member flag to
signal that the class can be destroyed safely then exiting without ever
returning? Then what about the implications for descendant classes? The
knots that could be tied by misuse due to misunderstanding or sheer
incompetence don't bear thinking about.

JB
 
A

Alf P. Steinbach

* n2xssvv g02gfr12930:
I'm still not happy destroying an object this way. Why not use a
static function passing the pointer and waiting for a member flag to
signal that the class can be destroyed safely then exiting without ever
returning?

Then you have one thread or at least fiber per object. We can disregard
that standard C++ doesn't support threads, because they're part of
practical C++ usage. But you really don't want one thread per object.

Then what about the implications for descendant classes?

The main implication is that derived classes ideally should ensure
dynamic allocation, e.g. by each descendant class declaring a protected
destructor, but often one just relies on the client code programmer's
good sense -- and of course that incorrect usage will be caught by
even the most cursory testing, such as trying to run the program.

The
knots that could be tied by misuse due to misunderstanding or sheer
incompetence don't bear thinking about.

That's a general problem in software development, yes, but isn't more of
a problem here than elsewhere, as far as I can see.
 
C

Clark S. Cox III

In a job interview I was asked about the statement below:

delete this;

Naturally I was horrified, yet they claimed they had used it.
Personally I'm pretty damn sure I could never justify this. So
is this a case of Lord Bryon, "Mad, bad, and dangerous to know",
or do you think you could ever justify using it?

Imagine a reference counted class that automatically deletes itself
when all of it's clients drop their references:

class Refcounted
{
int reference_count;
protected:
virtual ~Refcounted() { assert(reference_count <= 0); }
public:
Refcounted() : reference_count(0) {}
Refcounted(Refcounted const &) : reference_count(0) {}

void add_reference() { ++reference_count; }
void drop_reference() { if(--reference_count <= 0) delete this; }
};
 
A

Aleksey Loginov

Clark said:
Imagine a reference counted class that automatically deletes itself
when all of it's clients drop their references:

class Refcounted
{
int reference_count;
protected:
virtual ~Refcounted() { assert(reference_count <= 0); }

"assert ( reference_count < 0 )" or "reference_count (1)"
public:
Refcounted() : reference_count(0) {}
Refcounted(Refcounted const &) : reference_count(0) {}

void add_reference() { ++reference_count; }
void drop_reference() { if(--reference_count <= 0) delete this; }

same here.
 
W

W Marsh

Imagine a reference counted class that automatically deletes itself
when all of it's clients drop their references:

class Refcounted
{
int reference_count;
protected:
virtual ~Refcounted() { assert(reference_count <= 0); }
public:
Refcounted() : reference_count(0) {}
Refcounted(Refcounted const &) : reference_count(0) {}

void add_reference() { ++reference_count; }
void drop_reference() { if(--reference_count <= 0) delete this; }
};

Is it safe to "delete this;" from any method, as long as you don't
access any more class members? I imagine it just deletes itself, gets
to the end of the method and returns safely, right?
 
C

Colander

Hi,

I delete my threads that way.

This so I don't have to think about some fancy thing that
determines that my thread is done stopping. At first I deleted
the thread after calling stop, but that meant that I deleted it's
inner guts before he could finish calling all it's close statments.
(now the deleting and the closing happens in the same thread,
and it's easier to think about the flow)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top