www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Separate allocation and construction?

reply "Chris Williams" <yoreanon-chrisw yahoo.co.jp> writes:
If I wanted to allocate memory for a class and then call its 
constructor as two separate steps, while still having the object 
be managed by the garbage collector, is there any way to do that?

I believe that I've figured out a way to accomplish the first 
step, but not the second.

import std.stdio;

class Foo {
     this(string bar) {
         writeln(bar);
     }
}

void main() {
     Foo f = (new Foo[1])[0];
     f("Hello"); // doesn't compile
}
Jun 05 2014
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 5 June 2014 at 22:22:16 UTC, Chris Williams wrote:
 If I wanted to allocate memory for a class and then call its 
 constructor as two separate steps, while still having the 
 object be managed by the garbage collector, is there any way to 
 do that?
Check out std.conv.emplace http://dlang.org/phobos/std_conv.html#emplace First, allocate the memory block for the class. The size is __traits(classInstanceSize, Yourclass). Then slice it: enum size = __traits(classInstanceSize, YourClass); auto memory = GC.malloc(size)[0 .. size]; Then use emplace to do the construction: auto obj = emplace!YourClass(memory, ctor_args...); GC.malloc can be found in import core.memory; http://dlang.org/phobos/core_memory.html#malloc Note that you can also use other memory allocators here if you didn't want it gc'd.
Jun 05 2014
parent reply "Chris Williams" <yoreanon-chrisw yahoo.co.jp> writes:
On Thursday, 5 June 2014 at 22:25:03 UTC, Adam D. Ruppe wrote:
 On Thursday, 5 June 2014 at 22:22:16 UTC, Chris Williams wrote:
 If I wanted to allocate memory for a class and then call its 
 constructor as two separate steps, while still having the 
 object be managed by the garbage collector, is there any way 
 to do that?
Check out std.conv.emplace http://dlang.org/phobos/std_conv.html#emplace First, allocate the memory block for the class. The size is __traits(classInstanceSize, Yourclass). Then slice it: enum size = __traits(classInstanceSize, YourClass); auto memory = GC.malloc(size)[0 .. size];
Why slice? There seems to be a version of emplace that accepts a pointer, which is what GC.malloc() seems to return.
Jun 05 2014
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/05/2014 03:47 PM, Chris Williams wrote:
 On Thursday, 5 June 2014 at 22:25:03 UTC, Adam D. Ruppe wrote:
 On Thursday, 5 June 2014 at 22:22:16 UTC, Chris Williams wrote:
 If I wanted to allocate memory for a class and then call its
 constructor as two separate steps, while still having the object be
 managed by the garbage collector, is there any way to do that?
Check out std.conv.emplace http://dlang.org/phobos/std_conv.html#emplace First, allocate the memory block for the class. The size is __traits(classInstanceSize, Yourclass). Then slice it: enum size = __traits(classInstanceSize, YourClass); auto memory = GC.malloc(size)[0 .. size];
Why slice? There seems to be a version of emplace that accepts a pointer, which is what GC.malloc() seems to return.
That overload returns a T* but we need a class variable. I think we should accept it that it is reserved for non-class types (as the documentation also indicates). Ali
Jun 05 2014