新しい参照の作成
ローカル変数として参照を作成するときはつぎのようにする。 lwd_Reference r = new_lwd_Reference(new_C("3345g"),
(void (*)(void* object))C_finalize);
参照を生成するとき、第1引数としてオブジェクトのポインタを、第2引数にそのオブジェクトのデストラクタを指定する。構造体やクラスのメンバが参照の場合も同様に初期化できる。
関数から復帰時に自動的に解放されるオブジェクト
スコープドポインタとしての動作を確認する例を示す。テストに使用する簡単なクラス Cはつぎのようなもの。
/****************************************************************
test target C
****************************************************************/
static boolean cFinalized;
typedef struct C* C;
struct C {
char* string;
};
C new_C(char* string) {
C this = (C)malloc(sizeof(struct C));
if (this != null) {
cFinalized = false;
this->string = strdup(string);
}
printf("C object created.\n");fflush(stdout);
return this;
}
void C_finalize(C this) {
if (this != null) {
printf("C object finalized. %s\n", this->string);fflush(stdout);
if (this->string != null)
free(this->string);
free(this);
cFinalized = true;
}
}
コンストラクタとデストラクタがあるだけだが、デストラクタが実行されると外部変数の cFinalizedを trueにセットする。テストケースはつぎの通り。
static void function0() {
reference r = new_reference(new_C("3345g"),
(void (*)(void* object))C_finalize);
Assert_false("まだ削除されていないはず。", cFinalized);
}
void testAutoCollect(TestCase testCase) {
Assert_false("まだ削除されていないはず。", cFinalized);
function0();
Assert_true("削除されているはず。", cFinalized);
}
testAutoCollect関数から呼ばれた function0関数の中で、参照 rを生成する。関数復帰直前に cFinalizeは未だ falseであるが、testAutoCollect関数に戻ってきた後は cFinalizedが trueになる。
実行すると、標準出力にはつぎが出力されている。
[CUnit] ./ReferenceTest: testAutoCollect C object created. C object finalized. 3345gデストラクタを明示的に呼んではいないが、トレースログにはデストラクタが呼ばれている様子がわかる。
2万円以上のカードをパスケースに入れて改札機にタッチしますと他のカードが処理されることがあります。 -- それは不思議な現象だ