2016-11-16 3 views
1

私はいくつかの異なる動物の基本クラスである単純なクラスのAnimalを作成しました。次に、動物型オブジェクトをベクターに格納し、これらのオブジェクトで動作するメソッドをほとんど保持しない、Herdという別のクラスを作成しました。特定のクラスに一致する場合、ベースクラスオブジェクトのベクトルからオブジェクトを削除します

class Herd { 
public: 

Herd() {} 
~Herd() {} 

Herd operator+(Animal arg) { 
    vec.push_back(arg); 
    return *this; 
} 

void operator+=(Animal arg) { 
    vec.push_back(arg); 
} 

Herd operator-(Animal arg) { 
    std::vector<Animal>::iterator position = std::find(vec.begin(), vec.end(), arg); 
    if (position != vec.end()) // == myVector.end() means the element was not found 
     vec.erase(position); 
    return *this; 

} 


void make_noise() { 
    vector<Animal>::iterator v = vec.begin(); 
    while (v != vec.end()) { 
     v->give_sound(); 
     v++; 
    } 
    cout << endl; 
} 

private: 
vector<Animal> vec; 
}; 

問題は、Vectorから特定のオブジェクトを削除することです。私は演算子をオーバーロードしました - そして、私はいくつかのAnimalから派生したクラスをパラメータとして取り込み、ベクトルからこのクラスの最初の出現を取り除きたいと思いました:ベクトルがDog、Cat、Dogを含んでいるとしましょう - 、 犬。私は私のベクトルを反復処理し、argオブジェクトに一致する要素を見つけることでこれを行います。

残念なことに、Catを引数として渡した後、私のクラスはそれを動物型のように扱いますので、関数に渡すものは常に最初の要素が削除されます。

私は、オブジェクトではなくポインタのベクトルを作ることでこれを達成しようとしましたが、私の全体のプログラムは、この全部の動作を修正する方法を知らないエラーでカバーします。

+0

これはあなたを助けることができます:あなたのベクトルでhttp://stackoverflow.com/questions/2391679/why-do-we-need-virtual-functions-in-c – Fefux

+1

すべての項目は、ほとんどの派生クラスであります「動物」。より異質なベクトルである多形性を持たせるには、ポインタのベクトルを使うことができます。 'vector >'は合理的な選択肢の1つです。 –

+2

あなたはこれを読んでみたいと思うでしょう:[オブジェクトスライス*とは何ですか?](http://stackoverflow.com/a/274634/1322972) – WhozCraig

答えて

3

この場合、object slicingを体験します。それを動作させるには、ポインタを使用する必要があります。しかし、この場合はメモリを解放する必要がないので、std::shared_ptrまたはstd::unique_ptrを生ポインタの代わりにベクトルに格納することをお勧めします。

最後に、正確なタイプを確認するには、ポインタdynamic_castを試してみるか、typeidをチェックしてください。あるいは、ポリモーフィックのtype()関数を作成し、それを各派生クラスでオーバーライドして正確な型を返すこともできますが、この場合は恐らく過剰です。

vector<shared_ptr<Animal>> vec; 

for(auto animal : vec) 
{ 
    if(dynamic_cast<Cat*>(animal.get())) 
    { 
     //cat 
    } 
    if(typeid(*animal) == typeid(Cat)) 
    { 
     //also a cat 
    } 
} 
+1

インスタンスに(ノルウェーのフォレスト・キャット)< - cat < - アニメーション継承ツリーがある場合は、ダイナミック・キャストは成功しますが、typeidは明らかに異なります。 – Lanting

+0

@ Lanting、はい、それは本当ですが、それは "すべての猫のための何か"や "ノルウェーのすべての森林の猫(これは素晴らしい動物です、btw)のための何かをする"のようなケースではまだOPのために働くでしょう。 OPがやりたいこととまったく同じです。 – SingerOfTheFall

+0

私はスマートポインタに精通していません。もし私がそのようなベクトルを持っていれば、なぜこのようなメソッドができないのでしょうか?\t 'void operator + =(Animal * arg){ \t \t vec.push_back(arg); \t} '? – IFeel3

関連する問題