2

私は私がかなり気難しいと感じる問題を抱えています。趣味のプロジェクトでは、インターフェイスクラスへのポインタのstd :: listがあります。これは、インターフェイスのさまざまな具体的な実装を指します。

たとえば、次のようなものがあるとします。

class Seafood ...
class Fishstick : public Seafood ...
class Squid : public Seafood ...
...
std::list<Seafood*> buffet;

ビュッフェにさまざまなシーフードアイテムを入れたので、キッチンからさらに注文する必要があるかどうかを確認するために、利用できるフィッシュスティックの数を数えたいと思います。

RTTIまたはその不正な実装なしでこれを行うにはどうすればよいですか?RTTIを使用したい場合は、OOPに間違った方法でアプローチしている、および/またはソリューションを再設計する必要があると主張する記事をいくつか読みました。この問題に対処するいくつかのパターンまたは他の解決策はありますか?これまで何度も浮上しなければならなかったと思います。

ある種の仮想関数であることが明らかだと思っていましたが、RTTIの安っぽいバージョン、またはインターフェイスへの子孫に関する知識(CountIfFishstick / IsFishstick / Is(type))を組み込むことなく、これを行う方法を理解することはできません。 )。

編集:頭に浮かんだもう1つのことは、フィッシュスティックの1つのリスト、イカの1つのリストなどを保持することです。しかし、それは確かにインターフェイス/実装の目的全体を無効にします。

4

6 に答える 6

3

おそらく、ビジターパターンのバリエーションが必要です。たくさんあり、どれが欲しいかはわかりません。最新のC++デザインを入手し、Alexendrescuの実装を確認することをお勧めします。それ以外の場合は、「ビジターパターン」をグーグルで検索すると、1000kmのリンクが表示されます。

于 2012-05-25T18:25:28.617 に答える
1

複合パターンはどうですか?ビュッフェは本当にシーフードコレクションのコレクションです。FishStickとSquidは、アイテムの数を維持する複合パターンの「コンポーネント」です。したがって、Buffetがリストにある場合、Compositeをトラバースしてカウントを呼び出すことができます。

于 2012-05-26T07:56:14.430 に答える
1

ビジターパターンはあなたが探しているものです。また、Acyclicビジターと呼ばれる特別なバージョンのビジターもあります。これはRTTIを使用して元のビジターの問題の一部を解決するため、RTTIが常に間違っているとは限りませんが、実際に何をしているかを理解していない限り、ひどいコードにつながる可能性があります。 。

于 2012-05-25T18:28:54.273 に答える
1

おそらくname、基本クラスにアイテムの名前を返す関数があるので、それをキッチンに表示できます。これを使用して、アイテム数のマップにインデックスを付けます。

一般に、クラスごとに一意の識別子を返す関数を提供できます。

于 2012-05-25T19:18:12.500 に答える
0

C ++ 11を使用している場合は、次のようにすることができます。

int num_fish_sticks = std::count_if(buffer.begin(), buffet.end(),
    [](const SeaFood* sf) {sf->is_fish_stick()});

SeaFoodで純粋仮想関数を宣言する必要があります。

virtual bool is_fish_stick() const = 0;

それに応じてサブクラスに実装します。

編集:もちろん、サブクラスが多すぎると、これは厄介になる可能性があります。その場合は、RTTIだけを使用した方がよいでしょう。

int num_fish_sticks = std::count_if(buffer.begin(), buffet.end(),
    [](const SeaFood* sf) {typeid(*sf) == typeid(Fishstick)});
于 2012-05-25T18:38:20.773 に答える
0

私はあなたの問題があなたがそれを見せているよりもはるかに基本的だと思います:少なくともあなたがそれを提示したように、ここで継承を使用する理由はほとんどないようです。

継承は、オブジェクトの動作が異なる場合に役立ちますが、この場合、すべてのオブジェクトが本質的に同じ動作をしているように見えます。実際、動作はほとんどありません(「プレイデッド」を数えない限り)。

ビュッフェをモデル化する場合は、おそらくコンテナを使用します。ホットテーブルの各トレイは、ある程度の量の何かを保持するコンテナです。必要に応じて、テーブルをトレイのコンテナとしてモデル化し、(場合によっては)部屋をテーブルのコンテナとしてモデル化できます。

各トレイには「食品」(またはあなたがそれを呼びたいもの)が入っており、ほとんどの場合、名前と数量があります。唯一の動作は、食べ物が「提供された」ときを処理するタイマーであり、それに基づいて残りの食べ物を取り除く必要がある場合があります。完全な食事の一部としてのみ利用できるものと、サラダバーへのアクセスのみを購入したものに分けて利用できるものに分けるなど、それよりも少し多いかもしれません

于 2012-05-25T18:45:05.670 に答える