Hey, you have all the difficult bits already figured out!
There are only two problems in your code:
Firstly, when you derive a class that has a non-default constructor it does not automatically inherit to the derived class.
So when you call
creatures[3] = new Centaur("Florence");
it gives you an error because there is no constructor that takes a string argument.
So you have to define one.
The trick then is to specify that that particular constructor must call the base class constructor which takes a string argument, and not the default constructor.
This is done using the initialisation list syntax.
So the definition you are missing is:
Centaur::Centaur (string name) : Creature(name) { }
Same for Phoenix.
Now if you compile this, you will run into a second problem. Neither Centaur, Giant nor Phoenix know anything about creatureName. That's because it's declared private. If you want your derived classes to have that attribute then the qualifier you need is protected.
So here is the working code:
#include <iostream>
#include <string>
using namespace std;
class Creature
{
public:
Creature(string name);
virtual ~Creature();
virtual string name() const;
virtual string move() const = 0;
virtual bool mortal() const;
protected:
string creatureName;
};
class Phoenix : public Creature
{
public:
Phoenix (string name);
virtual string move() const;
virtual bool mortal() const;
};
class Centaur : public Creature
{
public:
Centaur (string name);
virtual string move() const;
};
class Giant : public Creature
{
public:
Giant(string name, int heavy);
virtual string move() const;
private:
int weight;
};
Creature::Creature(string name):creatureName(name)
{}
Creature::~Creature()
{}
string Creature::name() const
{
return creatureName;
}
bool Creature::mortal() const
{
return true;
}
Phoenix::Phoenix (string name) : Creature (name)
{ }
string Phoenix::move() const
{
return "Fly";
}
bool Phoenix::mortal() const
{
return false;
}
Centaur::Centaur (string name) : Creature (name)
{ }
string Centaur::move() const
{
return "trot";
}
Giant::Giant(string name, int heavy):Creature(name)
{
weight = heavy;
}
string Giant::move() const
{
if (weight < 20)
return "tromp";
else //weight is >= 20 tons
return "lumber";
}
//From here on the code was given in the assignment, and can't be changed
void animate(const Creature* c)
{
cout << c->name() << ", who is ";
if (c->mortal())
cout << "mortal";
else
cout << "immortal";
cout << ", will now " << c->move() << ".\n";
}
int main()
{
Creature* creatures[4];
creatures[0] = new Phoenix("Squawkes");
// Giants have a name and a weight in tons. Giants under 20 tons
// walk by tromping; giants weighing at least 20 tons lumber.
creatures[1] = new Giant("Frawp", 17);
creatures[2] = new Giant("Gridwulfa", 22);
creatures[3] = new Centaur("Florence");
cout << "Here are the creatures." << endl;
for (int k = 0; k < 4; k++)
animate(creatures[k]);
// Clean up the creatures before exiting
cout << "Cleaning up." << endl;
for (int k = 0; k < 4; k++)
delete creatures[k];
cin.get();
}