Предположим, что у меня есть следующая структура классов. Я хочу, чтобы иметь возможность определить, какой тип класса является элементом моего вектора 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();
}
Почему бы не сделать их подклассом животного, если вы не собираетесь использовать виртуальные методы, чтобы у обоих животных был метод .eat(). Есть ли причина, по которой им нужны разные имена методов, чтобы сделать то же самое? Тогда они не должны наследовать от того же класса. – Falmarri 2010-12-08 00:43:40
`dynamic_cast` - это« как это сделать правильно ». Это «неудобно», потому что, используя его здесь, вы неявно «не следуете принципу дизайна, который вам нужен». Явный эквивалент «по-разному» по той же причине, и это гораздо более очевидно, учитывая, как это написано. Кстати, используйте конструкции типа `foreach` для перебора контейнеров или, по крайней мере, используйте настоящие итераторы вместо индексов. См. Также http://stackoverflow.com/questions/4383250/why-should-i-use-foreach-instead-of-for-int-i0-ilength-i-in-loops. – 2010-12-08 01:55:21