假设我有以下类结构。我希望能够确定我的 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++ 中使用裸指针时要非常小心;在手动管理资源的地方很难编写正确的代码。在您的示例中,您没有释放指向的对象A
和 B
并因此泄露了它们。考虑使用智能指针,如 shared_ptr
,自动管理您的资源。)
关于c++ - 在基本 vector 的元素上调用派生方法(给出的示例),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4383174/