Это, вероятно, выходит далеко за рамки того, что вы спрашиваете, но с точки зрения дизайна, я думаю, что материал, относящийся к конкретной земле, должен быть внутри класса каждой земли, то есть мне немного неприятно видеть перегруженную функцию visit () Посетитель.
Член accept () для России и Англии, с другой стороны, один и тот же, и его следует перенести на Землю.
Вот как я бы это структурировал (взгляните на использование accept (), receive () и name ()):
#include <cstdio>
#include <vector>
using namespace std;
class Visitor;
class Land {
public:
virtual void accept(const Visitor *v);
virtual void arrive(void) const = 0;
virtual const char *name(void) const = 0;
};
class England : public Land {
public:
void arrive(void) const;
const char *name(void) const;
};
class Russia : public Land {
public:
void arrive(void) const;
const char *name(void) const;
};
class Visitor {
public:
void visit(const Land *l) const;
};
class Trip {
private:
vector<Land *> *l;
public:
Trip(vector<Land *> *_l);
void accept(Visitor *v);
};
/**** Implementations *****/
// underlying Land
void Land::accept(const Visitor *v) {
v->visit(this);
}
// England
const char *England::name(void) const {
return "England";
}
void England::arrive(void) const {
printf("Welcome to our lovely country, your passport please\n");
}
// Russia
const char *Russia::name(void) const {
return "Russia";
}
void Russia::arrive(void) const {
printf("Passport!!\n");
}
// Visitor
void Visitor::visit(const Land *l) const {
l->arrive();
printf("Hey, it'm in %s!\n", l->name());
}
// Trip
Trip::Trip(vector<Land *> *_l)
: l(_l) // !!! <Land *>
{
}
void Trip::accept(Visitor *v) {
for (unsigned i = 0; i < l->size(); i++) {
l->at(i)->accept(v);
}
}
/**** main *****/
int main()
{
England england;
Russia russia;
vector<Land *> trip_plan;
trip_plan.push_back(&england);
trip_plan.push_back(&russia);
trip_plan.push_back(&england);
Trip my_trip(&trip_plan);
Visitor me;
my_trip.accept(&me);
return 0;
}