Skip to content

Module 04 Solutions

Download Module 04 Solutions

Virtual functions for runtime polymorphism.

Animal.hpp
class Animal {
protected:
std::string _type;
public:
Animal();
Animal(const Animal& other);
Animal& operator=(const Animal& other);
virtual ~Animal(); // VIRTUAL destructor!
virtual void makeSound() const; // VIRTUAL for polymorphism
std::string getType() const;
};
Dog.cpp
Dog::Dog() : Animal() {
_type = "Dog";
}
void Dog::makeSound() const {
std::cout << "Woof!" << std::endl;
}

Test polymorphism:

const Animal* pet = new Dog();
pet->makeSound(); // "Woof!" (not "Generic animal sound")
delete pet; // Calls ~Dog() then ~Animal()

Animals with dynamically allocated Brain.

Dog.hpp
class Dog : public Animal {
private:
Brain* _brain; // Must deep copy!
public:
Dog();
Dog(const Dog& other);
Dog& operator=(const Dog& other);
~Dog();
void makeSound() const;
};
Dog.cpp
Dog::Dog() : Animal() {
_type = "Dog";
_brain = new Brain();
}
Dog::Dog(const Dog& other) : Animal(other) {
_brain = new Brain(*other._brain); // Deep copy
}
Dog& Dog::operator=(const Dog& other) {
if (this != &other) {
Animal::operator=(other);
delete _brain; // Free old
_brain = new Brain(*other._brain); // Deep copy
}
return *this;
}
Dog::~Dog() {
delete _brain;
}

Make Animal abstract with pure virtual function.

AAnimal.hpp
class AAnimal {
protected:
std::string _type;
public:
// ...
virtual void makeSound() const = 0; // Pure virtual
};
// Now: AAnimal a; is ERROR (cannot instantiate abstract class)

Interfaces and the clone pattern.

ICharacter.hpp
class ICharacter {
public:
virtual ~ICharacter() {}
virtual std::string const& getName() const = 0;
virtual void equip(AMateria* m) = 0;
virtual void unequip(int idx) = 0;
virtual void use(int idx, ICharacter& target) = 0;
};
Ice.cpp
AMateria* Ice::clone() const {
return new Ice(*this); // Return new copy
}
MateriaSource.cpp
AMateria* MateriaSource::createMateria(std::string const& type) {
for (int i = 0; i < 4; i++) {
if (_templates[i] && _templates[i]->getType() == type)
return _templates[i]->clone();
}
return NULL;
}