从基类对象的向量中移除匹配特定类的对象

Removing object from vector of base-class objects if matches specific class

本文关键字:对象 基类 向量      更新时间:2023-10-16

我创建了一个简单的类Animal,它是几个不同动物的基类。然后我创建了另一个类Herd,它将Animal类型的对象存储在vector中,并保留了一些操作这些对象的方法。

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中删除特定对象。我重载了操作符——我希望它以某种动物派生类作为参数,并从vector中删除该类的第一次出现:假设vector包含Dog, Cat, Dog——然后在调用了herd-Cat之后,我希望它是Dog, Dog。为此,我将遍历vector并查找与arg对象匹配的元素。

不幸的是,在传递Cat作为参数后,我的类将其视为动物类型,因此无论我传递给函数什么,第一个元素总是被删除。

我试图通过创建指针的向量来实现这一点,而不是对象,但是我的整个程序覆盖了错误,我不知道如何修复这些错误以使整个程序工作。

在这种情况下,您将体验对象切片。为了使它工作,你必须使用指针。但是,将std::shared_ptrstd::unique_ptr存储在vector中而不是原始指针中是个好主意,因为在这种情况下,您不必自己释放内存。

最后,检查确切的类型,你可以尝试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
    }
}