1

アイテムのコレクションを管理するプログラムを実行しています。それは本、雑誌、CDまたはDVDである可能性があります。これらはそれぞれ、クラスItemを継承するクラスです。これらのアイテムを保存するには、次のようなリストテンプレートを使用しています。

list<Item> items;

このリストは、クラスLibraryのオブジェクトライブラリ内にあります。

このリストを実行するために、私はこれを行っています:

for(list<Item>::iterator i = lib.itens.begin(); i != lib.itens.end(); ++i)

この時点まで、すべてが順調です。このループ内で派生クラスのメソッドを呼び出そうとすると、問題が発生します。例:

    for(list<Item>::iterator i = lib.itens.begin(); i != lib.itens.end(); ++i)
        (*i).lib.itens.show();

これらのメソッドを呼び出すにはどうすればよいですか?

4

2 に答える 2

2

ここには少なくとも2つの問題があります。まず、これを行う場合:

list<Item> items;

Itemこの場合、このリストには実際にはオブジェクトのみが含まれます。派生オブジェクトを入れようとすると、派生部分は単純に切り取られます。

1つの解決策は、代わりにポインターのリストを使用することです(ただし、メモリー管理の問題を回避するには、おそらくスマートポインターを使用する必要があります)。

しかし、それでも、2番目の問題は、(一般に)基本クラスへのポインターを介して派生クラス固有のメソッドを呼び出そうとしてはならないということです。ポリモーフィズムの要点は、階層全体に共通する機能を使用することに満足している場合にのみ、基本クラスのポインターに関して扱う必要があるということです(リスコフの置換原則を参照)。

于 2012-05-25T01:24:54.267 に答える
0

おそらくで定義virtual void show() = 0;する必要がありclass Itemます。これにより、show呼び出しは合法になりますが、同時に、でエラーが発生しlist<Item>ます。

基本的なエラーは、「ただの」ものを作成することはできませんがItemlist<Item>正確にそのリストを作成しようとすることです。showで純粋仮想関数として宣言することによりItem、コンパイラはこれを明示的に認識します。

于 2012-05-25T07:34:58.970 に答える