2

関連する質問で、汎用コンテナーの作成について尋ねました。ポリモーフィック テンプレートを使用するのが正しい方法のようです。

しかし、私の人生では、デストラクタをどのように書くべきかを理解することはできません。Tサンプル コンストラクターが別のポイントで割り当てられた (その次元と共に)配列を受け取る場合でも、割り当てられたメモリの所有者がコンテナーになるようにします。

次のようなことができるようになりたいです

MyContainer<float> blah();
...
delete blah;

MyContainer<ComplexObjectType*> complexBlah();
...
delete complexBlah;`

このようなことはできますか?スマートポインターなしでそれを行うことはできますか?

繰り返しますが、ご意見をお寄せいただきありがとうございます。

4

5 に答える 5

4

複合型へのポインタを格納する場合は、コンテナを次のように使用することをお勧めします。MyContainer<shared_ptr<SomeComplexType> >プリミティブ型の場合は、を使用するだけMyContainer<float>です。

shared_ptr、複合型が破棄されたときに適切に削除するように注意する必要があります。そして、プリミティブ型が破棄されても、派手なことは何も起こりません。


このようにコンテナを使用する場合、デストラクタはそれほど必要ありません。コンテナにアイテムをどのように保持しますか?STLコンテナーを使用しますか、それともヒープ上の配列を使用しますか?STLコンテナは、それ自体の削除を処理します。配列を削除すると、各要素のデストラクタが実行され、各要素がであるshared_ptr場合、shared_ptrデストラクタはそれ自体が保持しているポインタを削除します。

于 2008-10-04T00:40:43.567 に答える
1

おそらく、ここでスマート ポインターを使用することをお勧めします。これにより、問題が本当に単純化されます。ただし、演​​習として、指定された型がポインターであるかどうかを判断するのは非常に簡単です。大まかな実装 (もっとエレガントかもしれませんが、int2type を導入したくありません):

typedef char YesType;
typedef char NoType[2];

template<typename T>
struct IsPointer
{
typedef NoType  Result;
};
template<typename T>
struct IsPointer<T*>
{
typedef YesType Result;
};

template<typename T>
struct MyContainer
{
~MyContainer()
{
    IsPointer<T>::Result r;
    Clear(&r);
    delete[] data;
}
void Clear(YesType*)
{
    for (int i = 0; i < numElements; ++i)
        delete data[i];
}
void Clear(NoType*) {}

T*  data;
int numElements;

};

于 2008-10-04T08:30:42.447 に答える
0

それは可能ですが、これはかなり高度なものです。MyContainerのデストラクタに適切なものを選択させるには、ブーストMPLライブラリ(http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/index.html )のようなものを使用する必要があります。コンテナ上の個々のアイテムに対して行う必要がある一種の破壊。また、ブーストTypeTraitsライブラリを使用して、必要な削除の種類を決定できます(http://www.boost.org/doc/libs/1_36_0/libs/type_traits/doc/html/index.html)。含まれている型がポインタであるかどうかを判断し、それをどのように破棄する必要があるかを判断できる特性があると確信しています。MyContainerで使用したい、他の特定の削除要件がある他のタイプの特性を自分で実装する必要がある場合があります。それで頑張ってください!あなたがそれを解決するならば、あなたがそれをどのようにしたかを私たちに示してください。

于 2008-10-04T00:32:15.470 に答える
0

スマート ポインターを使用したくない場合は、部分的なテンプレートの特殊化を試すことができます。これにより、コンテナーをポインター型でインスタンス化するときにのみ使用されるテンプレートを作成できます。

于 2008-10-04T03:37:04.067 に答える
0

delete は、以前に で割り当てられたメモリの割り当てを解除するために使用されますnew。ここで delete を使用する必要はありません。blah と complexBlah が範囲外になると、それらは自動的に破棄されます。

yrpの回答は、テンプレートの特殊化を使用して、含まれているオブジェクトがポインターである場合はオブジェクトを削除し、そうでない場合は削除する 1 つの方法を示していますが、これは脆弱なソリューションのように思えます。このような動作が必要な場合は、正確な動作を提供するBoost Pointer Containerライブラリを使用することをお勧めします。標準ライブラリがそうでない理由は、コンテナー自体が、含まれているポインターを制御しているかどうかを認識していないためです。ポインターを認識できる型 (つまり、スマート ポインター) でラップする必要があります。

于 2008-10-10T17:21:27.040 に答える