Defining a custom *constructor* (not initializer!)
Mehrdad
wfunction at hotmail.com
Mon May 7 13:09:06 PDT 2012
On Monday, 7 May 2012 at 19:39:04 UTC, Steven Schveighoffer wrote:
>> I'm just asking if I can call the constructor manually, because
>> (like I wrote in my first post...) sometimes the C code you're
>> interoperating with takes control away from you, and just
>> calls a
>> callback on your behalf when constructing the object.
>
> I wasn't sure, but I just tried it out:
>
> import std.stdio;
> extern(C) void *_d_newclass(TypeInfo t);
>
> class C
> {
> int x;
> this(int x){this.x = x;}
> }
>
> void main()
> {
> C c = cast(C)_d_newclass(typeid(C));
> c.__ctor(1);
> writeln(c.x); // outputs 1
> }
>
> Seems to work
>
> -Steve
Nonono :( you still missed what I was saying.
Unless you're suggesting I replace _d_newclass, but that isn't
type-specific (and I certainly don't want to replace it globally).
Here's another attempt at the explanation:
I definitely CAN make a helper method to do this for me. It's the
whole factory pattern, etc.
The problems are that:
(1) The user wouldn't be able to say "new Window()" anymore (I
already explained why)
(2) The object couldn't be garbage collected.
Regarding #2, in case it doesn't make sense why:
It's because the C code takes control *AWAY* from you when you
tell it to destroy the object.
In my case, DestroyWindow(HWND) calls WndProc(WM_DESTROY,..),
which is a member function.
I CANNOT call DestroyWindow() in the finalizer, because then
WndProc would be called on a *derived* class during cleanup.
(It's the *same* issue as with the constructor.) So I'd have to
do this manually, which defeats the whole point of making the
object garbage-collectible in the first place.
What I'm *want* to be able to do is, basically, to specify that
I have a static method that will take care of finalizing an
object. (Something like: void finalize(Window o))
Then, when the object is being finalized, the garbage collector
would NOT call the object's finalizer directly. Instead, it would
call my STATIC method to do the rest of the cleanup.
The STATIC destruction method would call DestroyWindow() on the
handle, and DestroyWindow() would send the notification to the
window through a modified WndProc() (which I can always redirect,
to make it NOT be a member function during the following phase).
It would pass in a context parameter -- which would probably be
the Window object itself -- to my (redirected) WndProc.
The WndProc() would THEN call the Window's finalizer manually
(and tell the GC that the object is done being finalized, so it
can be collected).
I can't think of any "nice" way around this. Either the HWND
would have to be managed manually (in which case, that defeats
the purpose of using the GC to ensure its destruction along with
the object), or I would need an extra indirection in Window
(which REALLY overcomplicates the design, and introduces lots of
inheritance/template usage issues).
The thing is, I think this doesn't need any compiler support
either -- just a change in druntime. (I could be wrong though,
since it might involve modifying TypeInfo_Class, I'm not sure.)
Do you (or others) reckon a pull request to modify _d_newclass
and _d_delclass so that they would call a custom static
"constructor" and "destructor" for a class (if it specifies this
should be the case) might be accepted?
If there's the possibility then I might try hacking around with
it...
I can already see there being issues with inheritance, but I
think it would be fixable in some cases, and disallowable in
others. (Would obviously need to try it and see though.)
More information about the Digitalmars-d
mailing list