I have a main abstract class that I am provided and must create subclasses based on this class (THIS CANNOT BE MODIFIED):
class Spaceship
{
protected:
string m_name; // the name of the ship
int m_hull; // the hull strenght
public:
// Purpose: Default Constructor
// Postconditions: name and hull strength set to parameters
// -- INLINE
Spaceship(string n, int h)
{
m_name = n;
m_hull = h;
}
// Purpose: Tells if a ship is alive.
// Postconditions: 'true' if a ship's hull strength is above zero,
// 'false' otherwize.
// -- INLINE
bool isAlive()
{
return (m_hull > 0);
}
// Purpose: Prints the status of a ship.
// -- VIRTUAL
virtual void status() const = 0;
// Purpose: Changes the status of a ship, when hit by a
// weapon 's' with power level 'power'
// -- VIRTUAL
virtual void hit(weapon s, int power) = 0;
string getName() const
{
return m_name;
}
}; //Spaceship
So is an example of my child classes:
class Dreadnought: public Spaceship
{
int m_shield;
int m_armor;
int m_type;
public:
Dreadnought( string n, int h, int a, int s ): Spaceship( n, h ),m_shield( s ),m_armor(a),m_type(dreadnought){}
virtual void status() const
{
// implementation not shown to save space
}
virtual void hit(weapon s, int power)
{
// implementation not shown to save space
}
int typeOf(){ return m_type; }
};
in my main code I have an dynamic array of different types of Spaceships:
Spaceship ** ships;
cin >> numShips;
// create an array of the ships to test
ships = new Spaceship * [numShips];
Then i get input from the user to declare different types of ships in this array like:
ships[0] = new Dreadnought( name, hull, armor, shield );
my question is when I go to delete the array the correct destructor is not called, instead Spaceships is called, will this create a memory leak because the member vars "m_shield, m_armor" are not deleted and left hanging? If so is there a better way to get the type than using a var m_type and calling:
if( ships[i]->typeOf() == 0 )
delete dynamic_cast<Frigate*>(ships[i]);
else if( ships[i]->typeOf() == 1 )
delete dynamic_cast<Destroyer*>(ships[i]);
else if( ships[i]->typeOf() == 2 )
delete dynamic_cast<Battlecruiser*>(ships[i]);
else if( ships[i]->typeOf() == 3 )
delete dynamic_cast<Dreadnought*>(ships[i]);
else
delete dynamic_cast<Dropship*>(ships[i]);
Question #2 in the Spaceship class i declared: virtual int typeOf() = 0; and commented it out, is there a way i can implement this function in the child classes without declaring in the parent class so i can use it like shown above? when i dont declare it i get the compiler error:
error: 'class Spaceship' has no member named 'typeOf'
I assume this again has something to do with dynamic casing.
any help would be great,
Thanks nat
edit:
to clairify my first question would i have a memory leak if I just did:
delete ships[i];
or should i do:
delete dynamic_cast(ships[i]);
to remove member vars that are only in the derived classes?
Thnaks
You must add a virtual destructor to your Spaceship class. Then delete will properly destroy the elements from the array.
You must declare the typeOf() method in Spaceship. Otherwise, the compiler cannot know, that this is a valid member function.
You can avoid typeOf(), if you add the needed functionality as virtual member functions in your base class.
And even if you cannot modify your base class for whatever reasons, you can just do the dynamic_cast and test, if it yields a null pointer
Frigate *p = dynamic_cast<Frigate*>(ships[i]);
if (p != 0) {
// do something with a frigate
}
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