Self deleting class  
Author Message
dune17856





PostPosted: Wed Oct 24 11:58:48 PDT 2007 Top

Visual Studio C++ >> Self deleting class Hi,

Imagine:

CSomeClass* c = NULL;
c = new CSomeClass();
delete c;
c = new CSomeClass();
delete c;

So I must call delete c; to clean up memory.

However, instead of doing it like so.. isn't it equally valid to make class
self deleting?

So, if I do this:

class CSomeClass
{
CSomeClass();
virtual ~CSomeClass() { delete this; }
}

can I then simply do this?

CSomeClass* c = NULL;

c = new CSomeClass();
c = new CSomeClass();

What happens when I reassign the valiable to new instance? Will CSomeClass
self-delete itself at that point, or when application terminates?

Lisa

Visual Studio335  
 
 
Scott





PostPosted: Wed Oct 24 11:58:48 PDT 2007 Top

Visual Studio C++ >> Self deleting class "Lisa Pearlson" <EMail@HideDomain.com> wrote in message
news:EMail@HideDomain.com...
> Hi,
>
> Imagine:
>
> CSomeClass* c = NULL;
> c = new CSomeClass();
> delete c;
> c = new CSomeClass();
> delete c;
>
> So I must call delete c; to clean up memory.
>
> However, instead of doing it like so.. isn't it equally valid to make
> class self deleting?
>
> So, if I do this:
>
> class CSomeClass
> {
> CSomeClass();
> virtual ~CSomeClass() { delete this; }
> }
>
> can I then simply do this?
>
> CSomeClass* c = NULL;
>
> c = new CSomeClass();
> c = new CSomeClass();
>
> What happens when I reassign the valiable to new instance? Will CSomeClass
> self-delete itself at that point, or when application terminates?


Afraid not. When you reassign the variable to a new instance what you get
is a memory leak. I.e., you have overwritten the pointer to the first
object, so you then have no way to delete it.

--
Scott McPhillips [VC++ MVP]

 
 
Igor





PostPosted: Wed Oct 24 12:05:30 PDT 2007 Top

Visual Studio C++ >> Self deleting class Lisa Pearlson <EMail@HideDomain.com> wrote:
> So, if I do this:
>
> class CSomeClass
> {
> CSomeClass();
> virtual ~CSomeClass() { delete this; }
> }

This makes no sense. The destructor runs _because_ the object is being
destroyed. Trying to destroy it a second time while already under
destruction will likely just crash your program.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


 
 
Lisa





PostPosted: Wed Oct 24 12:47:48 PDT 2007 Top

Visual Studio C++ >> Self deleting class Then when would one use "delete this" ?
I see it used often in MFC's PostNcDestroy();

So if you don't use MFC, at which moment is "delete this" actually called?
In destructor?
How can the destructor be called withouth calling "delete" ?

Lisa


"Scott McPhillips [MVP]" <org-dot-mvps-at-scottmcp> wrote in message
news:%EMail@HideDomain.com...
> "Lisa Pearlson" <EMail@HideDomain.com> wrote in message
> news:EMail@HideDomain.com...
>> Hi,
>>
>> Imagine:
>>
>> CSomeClass* c = NULL;
>> c = new CSomeClass();
>> delete c;
>> c = new CSomeClass();
>> delete c;
>>
>> So I must call delete c; to clean up memory.
>>
>> However, instead of doing it like so.. isn't it equally valid to make
>> class self deleting?
>>
>> So, if I do this:
>>
>> class CSomeClass
>> {
>> CSomeClass();
>> virtual ~CSomeClass() { delete this; }
>> }
>>
>> can I then simply do this?
>>
>> CSomeClass* c = NULL;
>>
>> c = new CSomeClass();
>> c = new CSomeClass();
>>
>> What happens when I reassign the valiable to new instance? Will
>> CSomeClass self-delete itself at that point, or when application
>> terminates?
>
>
> Afraid not. When you reassign the variable to a new instance what you get
> is a memory leak. I.e., you have overwritten the pointer to the first
> object, so you then have no way to delete it.
>
> --
> Scott McPhillips [VC++ MVP]


 
 
Alex





PostPosted: Wed Oct 24 12:46:02 PDT 2007 Top

Visual Studio C++ >> Self deleting class "Lisa Pearlson" wrote:
> can I then simply do this?
>
> CSomeClass* c = NULL;
>
> c = new CSomeClass();
> c = new CSomeClass();
>
> What happens when I reassign the valiable to new instance?
> Will CSomeClass self-delete itself at that point, or when
> application terminates?

Other already answered that you'll get memory leak. It is
because pointer `c' knows nothing about about class'
destructor. Pointer just holds an address to the allocated
memory, that's all.

What you need here is so called "smart pointer". Smart
pointer is a class that wraps raw pointer and ensures the
release of acquired resources. You can implement such smart
pointer class by yourself, for example:

class CSomeClassPtr
{
public:
CSomeClassPtr(CSomeClass* p = NULL) : m_p(p) {}
~CSomeClassPtr() { delete m_p; }

public:
CSomeClass* operator ->()
{ return m_p; }

const CSomeClass* operator ->() const
{ return m_p; }

CSomeClass* operator =(CSomeClass* p)
{
if(p != m_p)
{
delete m_p;
m_p = p;
}

return m_p;
}

private:
CSomeClass* m_p;
};

Then you can use `CSomeClassPtr' instead of raw pointer:

CSomeClassPtr ptr;

ptr = new CSomeClass();
ptr = new CSomeClass();

However, there is similar smart pointer already implemented
in STL - `std::auto_ptr':

typedef std::auto_ptr<CSomeClass> CSomeClassPtr;

CSomeClassPtr p1(new CSomeClass);
CSomeClassPtr p2(new CSomeClass);
...


HTH
Alex

 
 
Alex





PostPosted: Wed Oct 24 13:05:43 PDT 2007 Top

Visual Studio C++ >> Self deleting class "Lisa Pearlson" wrote:
> Then when would one use "delete this" ?
> I see it used often in MFC's PostNcDestroy();

MFC framework has its rules. One of them is that
`PostNcDestroy' will be called by the framework as last call
for window object. That's why it's possible to put there
"delete this;" statement. If you call any member after
`PostNcDestroy' call, then you'll likely get a crash, since
`this' will be garbage already.

> So if you don't use MFC, at which moment is "delete this"
> actually called?

Withiut MFC framework nobody will call "delete this;". You
will need to call it yourself,

> In destructor?
> How can the destructor be called withouth calling "delete"
> ?

It can be called like this:

CSomeClass* c = ...
c->~CSomeClass();

however, it's quite an esoteric issue to begin with and very
rarely used in everyday practice. You just don't put "delete
this;" in destructor, that's it. If you want automatic
release of allocated memory, then use smart pointers.

Alex

 
 
Doug





PostPosted: Wed Oct 24 13:07:21 PDT 2007 Top

Visual Studio C++ >> Self deleting class On Wed, 24 Oct 2007 21:47:48 +0200, "Lisa Pearlson" <EMail@HideDomain.com> wrote:

>Then when would one use "delete this" ?
>I see it used often in MFC's PostNcDestroy();

This is done for some window types so that the window can automatically
destroy itself when the user closes it, or more generally, when someone
calls DestroyWindow. It's a fragile technique, because once the object is
deleted, no one can continue to use it, hence the comment in the MFC source
to the effect that "WM_NCDESTROY is the absolute last message received by
the window"... it had better be. Moreover, none of the functions in the
call chain leading to PostNcDestroy can use the object as the stack is
unwound as they return.

>So if you don't use MFC, at which moment is "delete this" actually called?
>In destructor?

Never in the destructor!

>How can the destructor be called withouth calling "delete" ?

For a dynamically allocated object, the ordinary way is by deleting the
object. You can call it yourself, but that's an advanced technique that is
rarely needed.

--
Doug Harrison
Visual C++ MVP
 
 
Igor





PostPosted: Wed Oct 24 13:09:47 PDT 2007 Top

Visual Studio C++ >> Self deleting class Lisa Pearlson <EMail@HideDomain.com> wrote:
> Then when would one use "delete this" ?
> I see it used often in MFC's PostNcDestroy();

In this case, the lifetime of the object is tied to lifetime of another
entity, an HWND handle. The object is notified that HWND is destroyed,
and chooses to destroy itself at the same time.

> So if you don't use MFC, at which moment is "delete this" actually
> called? In destructor?

Effectively, in the window proc in response to WM_NCDESTROY message.
This message is guaranteed to be the last ever sent to a window proc for
a given window.

> How can the destructor be called withouth calling "delete" ?

A destructor will also be called when a stack-based object goes out of
scope, or for an object with static duration when the program
terminates.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


 
 
Duane





PostPosted: Wed Oct 24 13:47:50 PDT 2007 Top

Visual Studio C++ >> Self deleting class
"Lisa Pearlson" <EMail@HideDomain.com> wrote in message
news:EMail@HideDomain.com...
> Hi,
>
> Imagine:
>
> CSomeClass* c = NULL;
> c = new CSomeClass();
> delete c;
> c = new CSomeClass();
> delete c;
>
> So I must call delete c; to clean up memory.
>
> However, instead of doing it like so.. isn't it equally valid to make
> class self deleting?
>
> So, if I do this:
>
> class CSomeClass
> {
> CSomeClass();
> virtual ~CSomeClass() { delete this; }
> }
>
> can I then simply do this?
>
> CSomeClass* c = NULL;
>
> c = new CSomeClass();
> c = new CSomeClass();

You have delete this in the dtor. When is the dtor invoked here?
If it was invoked, your "delete this" would either be redundant
or crash.

> What happens when I reassign the valiable to new instance? Will CSomeClass
> self-delete itself at that point, or when application terminates?

My quess would be that this would leak or crash. Why not just use a
smart pointer or no pointer?


 
 
Ben





PostPosted: Wed Oct 24 14:36:06 PDT 2007 Top

Visual Studio C++ >> Self deleting class
"Lisa Pearlson" <EMail@HideDomain.com> wrote in message
news:EMail@HideDomain.com...
> Hi,
>
> Imagine:
>
> CSomeClass* c = NULL;
> c = new CSomeClass();
> delete c;
> c = new CSomeClass();
> delete c;
>
> So I must call delete c; to clean up memory.
>
> However, instead of doing it like so.. isn't it equally valid to make
> class self deleting?
>
> So, if I do this:
>
> class CSomeClass
> {
> CSomeClass();
> virtual ~CSomeClass() { delete this; }

No! Not in the destructor.

This is ok though:

virtual void Release() { delete this; }

It is often combined with reference counting, a single threaded version
might look like:

int m_useCount;
virtual void AddRef() { m_useCount++; }
virtual void Release() { if (0 == --m_useCount) delete this; }

The other advantage of a self-deleting class is that it uses the memory
manager where the class is defined. When using DLLs you should respect
memory ownership and the same library that defines an object must both
create and destroy it, usually by using a factory function and a
self-deleting member function.

> }
>
> can I then simply do this?
>
> CSomeClass* c = NULL;
>
> c = new CSomeClass();
> c = new CSomeClass();
>
> What happens when I reassign the valiable to new instance? Will CSomeClass
> self-delete itself at that point, or when application terminates?
>
> Lisa
>


 
 
Giovanni





PostPosted: Wed Oct 24 15:25:48 PDT 2007 Top

Visual Studio C++ >> Self deleting class
"Ben Voigt [C++ MVP]" <EMail@HideDomain.com> ha scritto nel messaggio
news:EMail@HideDomain.com...

> It is often combined with reference counting, a single threaded version
> might look like:
>
> int m_useCount;
> virtual void AddRef() { m_useCount++; }
> virtual void Release() { if (0 == --m_useCount) delete this; }

It is like COM and ATL do (BTW: I believe they work also with
multithreading, maybe they use some multithreading-safe form of
increasing-decresing the counter, but I don't know precisely).

IMHO, the OP may consider using ATL for her development. She will have
robust classes and patterns to use to build quality apps, and not spend time
trying to kind of "reinventing the wheel" (see also another thread about
object-oriented C++ development to wrap Win32 APIs using Get/SetWindowLong,
etc.).

Giovanni



 
 
Ben





PostPosted: Thu Oct 25 07:35:58 PDT 2007 Top

Visual Studio C++ >> Self deleting class
"Giovanni Dicanio" <EMail@HideDomain.com> wrote in message
news:EMail@HideDomain.com...
>
> "Ben Voigt [C++ MVP]" <EMail@HideDomain.com> ha scritto nel messaggio
> news:EMail@HideDomain.com...
>
>> It is often combined with reference counting, a single threaded version
>> might look like:
>>
>> int m_useCount;
>> virtual void AddRef() { m_useCount++; }
>> virtual void Release() { if (0 == --m_useCount) delete this; }
>
> It is like COM and ATL do (BTW: I believe they work also with
> multithreading, maybe they use some multithreading-safe form of
> increasing-decresing the counter, but I don't know precisely).

The most common method is InterlockedIncrement/InterlockedDecrement.

>
> IMHO, the OP may consider using ATL for her development. She will have
> robust classes and patterns to use to build quality apps, and not spend
> time trying to kind of "reinventing the wheel" (see also another thread
> about object-oriented C++ development to wrap Win32 APIs using
> Get/SetWindowLong, etc.).

True, but it is still important to do it once yourself so you understand how
the frameworks behave.


 
 
Giovanni





PostPosted: Thu Oct 25 09:55:10 PDT 2007 Top

Visual Studio C++ >> Self deleting class
"Ben Voigt [C++ MVP]" <EMail@HideDomain.com> ha scritto nel messaggio
news:%EMail@HideDomain.com...

> True, but it is still important to do it once yourself so you understand
> how the frameworks behave.

Yes, for learning purposes, I do agree with you.

Giovanni


 
 
Alexander





PostPosted: Thu Oct 25 11:43:20 PDT 2007 Top

Visual Studio C++ >> Self deleting class Have a look at Boost smart pointers:

shared_ptr<>
scoped_ptr<>
intrusive_ptr<>

http://www.boost.org/

You approach of "delete this;" would be used with self-reference
counting and intrusive_ptr<>. Personally I mostly use shared_ptr<>.

As others already pointed out, your approach of calling delete this
in the destructor doesn't make the slightest sense.

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: EMail@HideDomain.com
MVP VC FAQ: http://vcfaq.mvps.org
=====================================

"Lisa Pearlson" <EMail@HideDomain.com> wrote in message
news:EMail@HideDomain.com...
> Hi,
>
> Imagine:
>
> CSomeClass* c = NULL;
> c = new CSomeClass();
> delete c;
> c = new CSomeClass();
> delete c;
>
> So I must call delete c; to clean up memory.
>
> However, instead of doing it like so.. isn't it equally valid to make
> class self deleting?
>
> So, if I do this:
>
> class CSomeClass
> {
> CSomeClass();
> virtual ~CSomeClass() { delete this; }
> }
>
> can I then simply do this?
>
> CSomeClass* c = NULL;
>
> c = new CSomeClass();
> c = new CSomeClass();
>
> What happens when I reassign the valiable to new instance? Will CSomeClass
> self-delete itself at that point, or when application terminates?
>
> Lisa
>