Существует огромное количество способов решения этой проблемы с использованием «концепций ОО», в зависимости от того, что вы хотите подчеркнуть.
Вот простейшее решение, которое я могу придумать:
class Animal {
public:
virtual void seenBy(Buddy&) = 0;
};
class Buddy {
public:
void see(Cat&) { /* ... */ }
void see(Squirrel&) { /* ... */ }
// ...
};
class Cat : public Animal {
public:
virtual seenBy(Buddy& b) { b.see(*this); }
};
class Squirrel : public Animal {
public:
virtual seenBy(Buddy& b) { b.see(*this); }
};
// classes for Frog, Coyote, Spot...
Если вам нужно несколько видов «воспринимающих» животных, просто создать виртуальную обертку для see
(с формой двойная отправка ):
// On a parent class
virtual void see(Animal&) = 0;
// On Buddy
virtual void see(Animal& a) { a.seenBy(*this); }
Выше необходимо, чтобы класс Animal
знал кое-что о классе Buddy
.Если вам не нравятся ваши методы в качестве пассивных глаголов и вы хотите отделить Animal
от Buddy
, вы можете использовать шаблон посетителя:
class Animal {
public:
virtual void visit(Visitor&) = 0;
};
class Cat : public Animal {
public:
virtual void visit(Visitor& v) { v.visit(*this); }
};
class Squirrel : public Animal {
public:
virtual void visit(Visitor& v) { v.visit(*this); }
};
// classes for Frog, Coyote, Spot...
class Visitor {
public:
virtual void visit(Cat&) = 0;
virtual void visit(Squirrel&) = 0;
// ...
};
class BuddyVision : public Visitor {
public:
virtual void visit(Cat&) { /* ... */ }
virtual void visit(Squirrel&) { /* ... */ }
// ...
};
class Buddy {
public:
void see(Animal& a) {
BuddyVision visitor;
a.visit(visitor);
}
};
Второй механизм может использоваться для целей, отличных от Buddyвидя животное (возможно, это животное видит Бадди).Это, однако, сложнее.
Обратите внимание, что ОО, безусловно, не единственный способ решить эту проблему.Существуют и другие решения, которые могут быть более практичными для этой проблемы, такие как сохранение свойств различных животных, которые заставляют Бадди лаять, есть, играть и т. Д. Это дополнительно отделяет класс Buddy
от класса Animal
(дажешаблон посетителя нуждается в исчерпывающем списке всего, что может воспринимать Бадди).