前のページ次のページ上に戻るホーム SophiaFramework UNIVERSE 5.3

13.6. クラスインスタンスを要素として扱う方法

コレクションには 4 バイトより大きな要素は格納できません。 クラスインスタンスをコレクションの要素として扱うには、 クラスインスタンスへのポインタ(4 バイト)を利用します。

具体的には、クラスインスタンスそのものではなく、 そのポインタをコレクションの要素にします。

[Note] 例外

ハッシュマップSFXLinkedHashMapSFXFlatHashMap)では、 文字列(SFXAnsiString / SFXWideString)をペア要素のキーにすることができます。

ただし、文字列をペア要素の値にすることはできません。 この場合は、文字列へのポインタをペア要素の値にします。

[Caution] メモリリーク

要素に格納されたポインタが指すヒープメモリ領域は、 要素が破棄されても自動的に解放されることはありません。

要素を破棄する前に、delete 文を利用して、 要素に格納されているポインタが指すヒープポインタを明示的に解放する必要があります。 この処理を怠ると、メモリリークが発生するかもしれません。

以下は、SFXAnsiString 文字列へのポインタを要素に持つ配列を定義するコードです。

// SFXAnsiString 文字列へのポインタを要素とする配列の定義
// クラスインスタンスを要素にするにはポインタを利用する
SFXArray<SFXAnsiStringPtr> array;

// 現在の配列の状態: array = () 

SFXArray::InsertLast 関数を使用して配列に 4 つの文字列の要素を追加します。

[Tip] Tip

要素には文字列へのポインタを格納します。

// 現在の配列の状態: array = () 

// "abc" を動的に生成し、"abc" へのポインタを要素に格納する
array.InsertLast(new SFXAnsiString("abc"));
// 現在の配列の状態: array = ( "abc" へのポインタ ) 

// "def" を動的に生成し、"def" へのポインタを要素に格納する
array.InsertLast(new SFXAnsiString("def"));
// 現在の配列の状態: array = ( "abc" へのポインタ, "def" へのポインタ) 

// "ghi" を動的に生成し、"ghi" へのポインタを要素に格納する
array.InsertLast(new SFXAnsiString("ghi"));
// 現在の配列の状態: array = ( "abc" へのポインタ, "def" へのポインタ, "ghi" へのポインタ) 

// "jkl" を動的に生成し、"jkl" へのポインタを要素に格納する
array.InsertLast(new SFXAnsiString("jkl"));
// 現在の配列の状態: array = ( "abc" へのポインタ, "def" へのポインタ, "ghi" へのポインタ, "jkl" へのポインタ) 

// "mno" を動的に生成し、"mno" へのポインタを要素に格納する
array.InsertLast(new SFXAnsiString("mno"));
// 現在の配列の状態: array = ( "abc" へのポインタ, "def" へのポインタ, "ghi" へのポインタ, "jkl" へのポインタ, "mno" へのポインタ) 

インデックスを利用して、要素の文字列を参照したり、 要素に文字列を設定することが可能です。

// 現在の配列の状態: array = ( "abc" へのポインタ, "def" へのポインタ, "ghi" へのポインタ, "jkl" へのポインタ, "mno" へのポインタ) 

// array[1] が指す文字列をデバッグウィンドウに表示する
TRACE("%s", array[1]->GetCString());

// array[0] に "xyz" へのポインタを設定する

// "delete array[0];" よりも前に"array[0] = new SFXAnsiString("ghi");" を実行すると、
// メモリリークが発生する

// array[0] が指す文字列を削除する
delete array[0]; 

array[0] = new SFXAnsiString("xyz");
// 現在の配列の状態: array = ( "xyz" へのポインタ, "def" へのポインタ, "ghi" へのポインタ, "jkl" へのポインタ, "mno" へのポインタ) 

SFXArray::GetSize 関数を呼び出して、 配列の要素である文字列の数を取得します。

// 現在の配列の状態: array = ( "xyz" へのポインタ, "def" へのポインタ, "ghi" へのポインタ, "jkl" へのポインタ, "mno" へのポインタ) 

SInt32 n = array.GetSize(); // n = 5

インデックスを指定して SFXArray::Remove 関数を呼び出して、 配列の要素である文字列を部分的に削除します。

// 現在の配列の状態: array = ( "xyz" へのポインタ, "def" へのポインタ, "ghi" へのポインタ, "jkl" へのポインタ, "mno" へのポインタ) 

// array[3] から array[4] までの要素を削除する
SInt32 i;

for (i = 3; i < 5; ++i) {
    delete array[i];
}

array.Remove(3, 5);
// 現在の配列の状態: array = ( "xyz" へのポインタ, "def" へのポインタ, "ghi" へのポインタ) 
[Note] 注意

メモリリークを防止するために、 削除する前に delete 文を利用して要素のポインタが指す文字列を削除します。

SFXArray::Clear 関数を呼び出して、 配列の要素である文字列をすべて削除します。

// 現在の配列の状態: array = ( "xyz" へのポインタ, "def" へのポインタ, "ghi" へのポインタ) 

SFXArray<SFXAnsiStringPtr>::Iterator iterator = array.GetFirstIterator();

while (iterator.HasNext()) {

    SFXAnsiStringPtr str = iterator.GetNext();

    delete str;
}

array.Clear(); 
// 現在の配列の状態: array = () 
[Note] 注意

メモリリークを防止するために、 削除する前に delete 文を利用して要素のポインタが指す文字列をすべて削除します。

SFXArray::FirstIndexOf / SFXArray::LastIndexOf 関数や、 SFXArray::Contains 関数の引数に文字列を指定することはできません。

これと同等のことを行うには、列挙子を利用して以下のように記述します。

// FirstIndexOf() / LastIndexOf() / Contains() の引数に文字列は指定できない
// 例えば、
//    "SInt32 n = array.FirstIndexOf("abc");" 
//    "SInt32 n = array.LastIndexOf("abc");" 
//    "Bool b = array.Contains("abc");"
// は、すべて不正。


// "SInt32 n = array.FirstIndexOf("abc");" は、以下のように記述する

SFXArray<SFXAnsiStringPtr>::Enumerator etor = array.GetFirstEnumerator();

SInt32 n(-1);
SInt32 i(0);

while (etor.HasNext()) {

    SFXAnsiStringPtr string = etor.GetNext();

    if (string->Equals("abc")) {

        n = i;
        break;
    }
    i++;
}
// n に見つかったインデックス値が格納される。見つからなかった場合は -1。


// "SInt32 n = array.LastIndexOf("abc");" は、以下のように記述する

SFXArray<SFXAnsiStringPtr>::Enumerator etor = array.GetLastEnumerator();

SInt32 n(-1);
SInt32 i = array.GetSize() - 1;

while (etor.HasPrevious()) {

    SFXAnsiStringPtr string = etor.GetPrevious();

    if (string->Equals("abc")) {

        n = i;
        break;
    }
    i--;
}
// n に見つかったインデックス値が格納される。見つからなかった場合は -1。



// "Bool b = array.Contains("abc");" は、以下のように記述する

SFXArray<SFXAnsiStringPtr>::Enumerator etor = array.GetFirstEnumerator();

Bool b(false);

while (etor.HasNext()) {

    SFXAnsiStringPtr string = etor.GetNext();

    if (string->Equals("abc")) {

        b = true;
        break;
    }
}
// 見つかった場合、 b に true が格納される。見つからなかった場合は false。

サンプルコード:クラスインスタンスのリスト処理