Defining a custom *constructor* (not initializer!)
Steven Schveighoffer
schveiguy at yahoo.com
Fri May 11 06:09:18 PDT 2012
On Mon, 07 May 2012 19:00:22 -0400, Mehrdad <wfunction at hotmail.com> wrote:
> On Monday, 7 May 2012 at 21:07:15 UTC, Steven Schveighoffer wrote:
>> I guess I don't really understand that. Who is responsible for
>> cleaning up your class instance? The way I was understanding your
>> description, I thought it was the C window runtime calling a callback
>> you provide to it. Why do you need to have the GC clean it up?
>
>
> Ah, I see why that's confusing.
>
> Here's a (hopefully better) explanation:
>
> Just as with any other object that represents an outside resource (e.g.
> a File/Stream/whatever), the lifetime of the unmanaged object should
> always follow the lifetime of the managed object.
>
> In other words, this means that the creation of a Window object MUST be
> associated with the system call CreateWindow() (which in turns calls the
> window dispatcher function, WndProc, with the message WM_CREATE).
>
> And, more importantly, this means that if the GC collects the Window
> object, then DestroyWindow() MUST be called on the kernel object, so
> that the window handle doesn't get leaked.
>
> Just as with any other resource.
>
>
> The trouble is that, as-is, this behavior is NOT implementable with a
> simple Window class whose constructor calls CreateWindow() and whose
> destructor calls DestroyWindow().
>
> Why? Because if you were to do that in the constructor or destructor,
> the system would call back your WndProc() function, which is a *virtual*
> function meant to be overridden in the derived classes (so that they can
> handle events, such as the creation/destruction of the window, or the
> calculation of the window size, etc. properly).
>
> That would mean your WndProc() in the derived instance would be called
> *before* the constructor of the derived instance is called, which is
> obviously not what you want.
OK, I understand what you are saying now.
What about using NVI?
class Window
{
protected void processMessage_impl(int message) // virtual call
{}
final public void processMessage(int message)
{
if(message == WM_CREATE)
{
// handle specially
}
else if(message == WM_DELETE)
{
// handle specially
}
else
{
processMessage_impl(int message);
}
}
private HWND window;
this()
{
window = CreateWindow(&processMessage); // or whatever mechanism, you
get the idea
}
~this()
{
DestroyWindow(window);
}
}
-Steve
More information about the Digitalmars-d
mailing list