I'm writing a simplistic game to learn get some more C++ experience, and I have an idea where I feel polymorphism almost works, but doesn't. In this game, the Party
moves fairly linearly through a Map
, but can occasionally encounter a Fork
in the road. A fork is (basically) an std::vector<location*>
.Originally I was going to code something like the following into the a Party
member function:
if(!CurrLocation->fork_.empty())
// Loop through forks and show options to the player, go where s/he wants
else
(CurrLocation++)
But I was wondering if some variant of the following might be better:
CurrLocation = CurrLocation->getNext();
With Fork actually being derived from Location, and overloading some new function getNext()
. But in the latter case, the location
(a low level structure) would have to be the one to present the message to the user instead of "passing this back up", which I don't feel is elegant as it couples location
to UserInterface::*
.
Your opinions?
Polymorphism helps in reducing the coupling between different functionalities. Method overloading can be implemented on constructors allowing different ways to initialize objects of a class. This enables you to define multiple constructors for handling different types of initializations.
Polymorphism allows us to perform a single action in different ways. In other words, polymorphism allows you to define one interface and have multiple implementations. The word “poly” means many and “morphs” means forms, So it means many forms.
Polymorphism in C++ allows us to reuse code by creating one function that's usable for multiple uses. We can also make operators polymorphic and use them to add not only numbers but also combine strings. This saves time and allows for a more streamlined program.
Advantages of PolymorphismIt helps the programmer to reuse the codes, i.e., classes once written, tested and implemented can be reused as required. Saves a lot of time. Single variable can be used to store multiple data types. Easy to debug the codes.
All problems can be solved by adding a level of indirection. I would use your suggested variant, and decouple Location from Party by allowing getNext to accept an object that resolves directional choices. Here is an example (untested):
class Location;
class IDirectionChooser
{
public:
virtual bool ShouldIGoThisWay(Location & way) = 0;
};
class Location
{
public:
virtual Location * GetNext(IDirectionChooser & chooser)
{
return nextLocation;
}
virtual Describe();
private:
Location * nextLocation;
};
class Fork : public Location
{
public:
virtual Location * GetNext(IDirectionChooser & chooser)
{
for (int i = 0; i < locations.size(); i++)
if (chooser.ShouldIGoThisWay(*locations[i]))
return locations[i];
}
virtual Describe();
private:
vector<Location *> locations;
};
class Party : public IDirectionChooser
{
public:
void Move()
{
currentLocation = currentLocation->GetNext(GetDirectionChooser());
}
virtual IDirectionChooser & GetDirectionChooser() { return *this; }
virtual bool ShouldIGoThisWay(Location & way)
{
way.Describe();
cout << "Do you want to go that way? y/n" << endl;
char ans;
cin >> ans;
return ans == 'y';
}
};
You should use polymorphism as long as it makes sense and simplifies your design. You shouldn't use it just because it exists and has a fancy name. If it does make your design simpler, then it's worth the coupling.
Correctness and simplicity should be the ultimate goal of every design decision.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With