c++ - 在基本 vector 的元素上调用派生方法(给出的示例)

标签 c++ vector derived object-slicing

假设我有以下类结构。我希望能够确定我的 Animal vector 中的元素是什么类类型,以便我可以对其执行特定于子类的方法。下面的例子应该证明:

#include <iostream>
#include <vector>

using namespace std;

class Animal {
    public:
    int foodcount;

    Animal() {
        foodcount = 0;
        cout << "An animal was created.\n";
    }
    virtual ~Animal() {
        cout << "An animal was destroyed.\n";
    }
};

class Lion : public Animal {
    public:
    Lion() {
        cout << "A lion was created.\n";
    }
    virtual ~Lion() {
        cout << "A lion was destroyed.\n";
    }
    void chowMeat(int howmuch) {
        foodcount += howmuch;
    }
};

class Butterfly : public Animal {
    public:
    Butterfly() {
        cout << "A butterfly was created.\n";
    }
    virtual ~Butterfly() {
       cout << "A butterfly was destroyed.\n";
    }
    void drinkNectar(int howmuch) {
       foodcount += howmuch;
    }
};

int main() {
    Animal* A = new Lion();
    Animal* B = new Butterfly();
    vector<Animal*> v;

    v.push_back(A);
    v.push_back(B);

    // a little later

    for (int i=0; i<v.size(); i++) {
        if (v[i] is a Lion) v[i]->chowMeat();  // will not work of course
        if (v[i] is a Butterfly) v[i]->drinkNectar();   // will not work of course
    }

    std::cin.get();
    return 0;
}

很明显标记的代码是行不通的,但是我要怎么做才能做到呢?是否有我应该遵循但没有遵循的解决方法或设计原则?我研究过 dynamic_cast 但我知道这很不妥当。那么应该如何正确操作呢?

在 Java 中,我会这样做:

if (v.get(i).getClass() == Lion.class) {
    ((Lion)v.get(i)).chowMeat();
}
if (v.get(i).getClass() == Butterfly.class) {
    ((Butterfly)v.get(i)).drinkNectar();
}

最佳答案

理想情况下,您可以向基类添加一个虚函数,void eat(int quantity) 并在派生类中覆盖该函数。

在这种情况下,使函数成为非虚函数并在基类中实现它甚至可能是有意义的,因为两个派生类做完全相同的事情。

除此之外,您可以使用dynamic_cast 来测试对象的动态类型:

if (Lion* lion = dynamic_cast<Lion*>(v[i])) {
    lion->chowMeat(42); 
}
else if (Butterfly* butterfly = dynamic_cast<Butterfly*>(v[i])) {
    butterfly->drinkNectar(42);
}
// etc.

(换句话说,在 C++ 中使用裸指针时要非常小心;在手动管理资源的地方很难编写正确的代码。在您的示例中,您没有释放指向的对象AB 并因此泄露了它们。考虑使用智能指针,如 shared_ptr,自动管理您的资源。)

关于c++ - 在基本 vector 的元素上调用派生方法(给出的示例),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4383174/

相关文章:

algorithm - 按此向量中映射的成员对对象向量进行排序

Java Vector<int[]> int[] 的引用还是复制?

C++:我可以编写一个从 T 派生的模板类吗?

c++ - 避免切片异常类型 (C++)

c++ - 是否可以从 readelf 命令读取结果

C++11 thread_local 析构函数行为

c++ - 混合 C 和 C++ 代码的静态分析怪异符号行为

c++ - Symbian 获取内容类型?

javascript - Three.js - 将网格速度转换为网格旋转

c++使用来自基类的指针访问派生类