2

同じ抽象基本クラスを継承する 2 つのクラスがあります。

class base
{ virtual void something() = 0; };

class a : public base
{
     void something();
};

class b : public base
{
     void something();

     // This is what I want: a list where I can store values of type a
     // and of type b
     // std::list<a & b> objs;
};

生/スマート ポインターのリスト ( list<base*> obj_ptrs) を使用できますが、このリストを使用するにはどうすればよいですか?

b b_obj;
b_obj.obj_ptrs.push_back(new a());

// Who have to delete this pointer? Who use the class or who design
// the class in the object destructor?

// The following is valid for c++11
auto p = b_obj.obj_ptrs.back();
// But if i'm using c++03?

クラスを使用する人がこれを行う可能性があることを望みます:

a a_obj;
b b_obj;

b_obj.obj_ptrs.push_back(a);
b_obj.obj_ptrs.push_back(b);

この作業を行うには、クラスをどのように設計すればよいですか?

4

4 に答える 4

4

生/スマート ポインターのリスト ( list<base*> obj_ptrs) を使用できますが、このリストを使用するにはどうすればよいですか?

dynamic_cast仮想関数を呼び出すか、例外的な状況では、 を使用してポインター型をa*またはに変換することにより、それらと多態的に対話しますb*

誰がこのポインターを削除する必要がありますか?

所有権のスキームを決定する必要があります。1 つのアプローチは、リストにスマート ポインター (通常unique_ptr、またはshared_ptr特殊な状況で) を格納し、リストから削除すると自動的に削除することです。もう 1 つの方法は、オブジェクトをリストとは別に管理し、生のポインターをリストに入れることです。

// The following is valid for c++11
auto p = b_obj.obj_ptrs.back();
// But if i'm using c++03?

に相当しbase * p = b_obj.obj_ptrs.back();ます。auto魔法のように動的ポインター型を与えるわけではなく、静的ポインター型の単なるショートカットです。

この作業を行うには、クラスをどのように設計すればよいですか? (さまざまな種類のオブジェクトを格納する)

さまざまなタイプのオブジェクトの格納は、識別されたユニオンを使用して行うことができます。基本的には、どのユニオン メンバーがアクティブであるかを追跡するための追加のメタデータを含むユニオンです。これらを C++ で実装するのは非常に難しいですが、Boost.VariantまたはBoost.Anyを使用できます。これには、共通の基本クラスや、格納されている型からのその他のサポートが必要ないという利点があります。(非抽象) タイプの任意のセットを使用できます。

于 2012-07-05T12:51:08.973 に答える
2

共有ポインタのリストを使用することは、非常に安全で簡単です。

std::list<std::shared_ptr<base>> the_list;

追加するオブジェクトが で割り当てられるという規則を維持する場合、オブジェクトが参照カウントされなくなったときに、 が削除を処理しますnewshared_ptr(shared_ptr参照カウントを実装します)

std::shared_ptr<a> my_a(new a);
std::shared_ptr<b> my_b(new b);

the_list.push_back(my_a);
the_list.push_back(my_b);

std::shared_ptr<base> my_object = the_list.back();
于 2012-07-05T12:49:46.510 に答える
0

std::list<a & b>オブジェクト; 正しくない。私はあなたが意味std::list<base*> objsしていると思いstd::list<base&> objs ます

a a_obj;
b b_obj;
b_obj.objs.push_back(&a_obj);
b_obj.objs.push_back(&b_obj);
base* p = b_obj.objs.back();

またはポインタの代わりに参照を使用します。

于 2012-07-05T12:46:04.027 に答える
0

本当に、aまたはbそれらの型の値のみを保存することに関心がある場合は、内部でstd::list<a>1 つと 1 つを保持し、両方で適切なパブリック メンバーをオーバーロードし、適切なリストに転送することを検討してください (たとえば、このような使用法が推奨されます)。std::list<b>abb obj; obj.push_back(value);

aオブジェクト間の挿入の相対的な順序bを気にせず、所有権について心配する必要がなく、eg を使用する場合と比較して動的割り当てのコストを支払う必要がなく、必要なstd::unique_ptr<base>ものに最も近いものを表現する限り、これは機能します。 .

于 2012-07-06T06:50:12.410 に答える