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