C++だといわゆる配置new(Placement New)、自分で確保したメモリ領域にクラスのインスタンスを作ることができる。
D言語だとどう書けばいいのか。
クラスアロケータとか言う奴がある。クラス定義の中で、
new (uint size) {
...
}
と書いて、最後に自分のポインタを返せばいいらしい。しかしながら、"Note: Class allocators are deprecated in D2. "であるので、この方法は使わない。
じゃあ代替手段はと言うと、こういうのがある。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std.stdio; | |
class C | |
{ | |
this(string arg = "") | |
{ | |
writeln("constructor is called." ~ arg); | |
} | |
~this() | |
{ | |
writeln("destructor is called."); | |
} | |
} | |
T allocate(T, Args...)(Args args) | |
{ | |
import std.conv : emplace; | |
import core.stdc.stdlib : malloc; | |
auto size = __traits(classInstanceSize, T); | |
auto memory = malloc(size)[0..size]; | |
if(!memory) | |
{ | |
import core.exception : onOutOfMemoryError; | |
onOutOfMemoryError(); | |
} | |
return emplace!(T, Args)(memory, args); | |
} | |
void deallocate(T)(T obj) | |
{ | |
import core.stdc.stdlib : free; | |
destroy(obj); | |
free(cast(void*)obj); | |
} | |
void main() | |
{ | |
auto test = allocate!C("YEAH!"); | |
scope (exit) deallocate(test); | |
} |
__traitsでクラスインスタンスのサイズを取得して、mallocしてstd.convのemplaceでコンストラクタを呼び出せばいいようだ。
逆にdeallocateは、destroyしてから、クラスへのポインタをvoid*にcastして、freeに渡す。
C言語の機能はcore.stdc以下にあるようだ。
↑のコードではGCを利用するつもりが無いから元のコードにあるGC云々はしてないけど、これでGCを使わなくてもmallocでクラスを作れます。
0 件のコメント:
コメントを投稿