假设我有如下的类结构。我希望能够确定我的Animal向量中的元素是什么类类型,这样我就可以对它执行子类特定的方法。下面的示例将演示:
#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();
}发布于 2010-12-08 08:42:11
理想情况下,您应该向基类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,自动管理您的资源。)
发布于 2010-12-08 08:41:27
循环的目的是什么?是用来吃东西的吗?在这种情况下,将virtual void consumeFood(int howMuch)添加到基类,并在派生类中重写它。
发布于 2010-12-08 09:02:20
为什么不吃()呢?
class Animal {
public:
int foodcount;
Animal() {
foodcount = 0;
cout << "An animal was created.\n";
}
virtual ~Animal() {
cout << "An animal was destroyed.\n";
}
virtual void eat(int howMuch) {
foodcount += howmuch;
}
};
class Lion : public Animal {
public:
virtual void eat(int howmuch) {
Animal::eat(howmuch + 19);
}
};
class Butterfly : public Animal {
void eat(int howmuch) {
Animal::eat(howmuch / 1000);
}
};
class Tribble: public Animal
{
void eat(int howmuch) {
throw DontFeedTribles();
}
};
int main() {
std::auto_ptr<Animal> A = new Lion();
std::auto_ptr<Animal> B = new Butterfly();
vector<Animal*> menagerie;
menagerie.push_back(A.get());
menagerie.push_back(B.get());
BOOST_FOREACH(Animal* animal, menagerie)
{
animal->eat(10000);
}
std::cin.get();
return 0;
}https://stackoverflow.com/questions/4383174
复制相似问题