qiezi 发表于 2013-1-27 06:25:54

D语言 在栈上分配对象 以及 无需GC拖管对象

一、栈上分配对象

C++可以轻易实现在栈上和堆上分配对象,例如下面的代码:
class Foo{};Foo foo;//在栈上分配Foo* foo = new Foo; //在堆上分配
在栈上分配对象是C++相较于java的一大优势,可以轻松实现RAII。

D语言也可以实现这2种分配方式:
Foo foo = new Foo; // 在GC堆上分配scope Foo foo = new Foo; // 在栈上分配
C++和D在栈上分配的对象,在分配时都会调用构造函数,超出作用域时都会自动析构。

这里顺便提一下0.175版以前,D的栈上对象的一个小陷阱:
scope Foo foo1 = new Foo;scope Foo foo2 = new Foo;scope Foo foo3 = foo1;
用了3个scope关键字,但实际上只有2个对象需要。0.175版以前,对象实际上是分配在堆上的,程序会死锁在这里。0.175版的scope对象真正在栈上分配,这个BUG也改掉了。

二、无需GC拖管的对象

C++除了在栈上和堆上分配对象以外,还支持一种由用户分配空间的方式,用户需要分配出一段内存空间,并且自己调用placement new。

char* mem = new char;Foo* foo = new(mem)Foo;foo->~Foo();delete[] mem;
D语言同样支持这种低层操作,以下代码摘自: http://www.digitalmars.com/techtips/class_objects.html
import std.c.stdlib;import std.outofmemory;// This is part of the D internal runtime library supportextern (C) void _d_callfinalizer(void *p);class Foo{    this(int x, char c) { ... }    ~this() { ... }}Foo alloc_Foo(int x, char c){    ClassInfo ci = Foo.classinfo;    Foo f;    void *p;    p = std.c.stdlib.malloc(ci.init.length);    if (!p)std.outofmemory._d_OutOfMemory();    // Initialize it    (cast(byte*)p) = ci.init[];    f = cast(Foo)p;    // Run constructor on it    f._ctor(x, c);    return f;}void free_Foo(Foo f){   void* p = cast(void*)f;    if (p)    {_d_callfinalizer(p);// call destructorstd.c.stdlib.free(p);    }}
这在实现对象池或自定义GC时可能有帮助。使用上比C++麻烦,不过这不是个推荐使用的特性,能够驾奴这个特性的人,自然不害怕这点代码。
页: [1]
查看完整版本: D语言 在栈上分配对象 以及 无需GC拖管对象