Teaching Notes: Module 04
Key Learning Objectives
Section titled “Key Learning Objectives”- Virtual functions and polymorphism
- Virtual destructors
- Abstract classes
- Interfaces (pure abstract classes)
- Deep copy with dynamic memory
Exercise 00: Polymorphism
Section titled “Exercise 00: Polymorphism”The Key Insight
Section titled “The Key Insight”const Animal* pet = new Dog();pet->makeSound(); // Without virtual: "Generic animal sound" // With virtual: "Woof!"Common Mistakes
Section titled “Common Mistakes”-
Forgetting virtual keyword
class Animal {public:void makeSound(); // NOT polymorphicvirtual void makeSound(); // Polymorphic}; -
Not testing with base pointer
- The whole point is treating Dog/Cat as Animal
WrongAnimal Demonstration
Section titled “WrongAnimal Demonstration”Create identical classes without virtual to show the difference.
Exercise 01: Deep Copy with Brain
Section titled “Exercise 01: Deep Copy with Brain”Key Concept
Section titled “Key Concept”Dog and Cat have Brain* - must deep copy!
Common Mistakes
Section titled “Common Mistakes”-
Shallow copy (DEFAULT)
// Default copy: both point to SAME Brain!Dog original;Dog copy = original; // DISASTER -
Forgetting virtual destructor
const Animal* pet = new Dog();delete pet; // Without virtual ~Animal(): Dog's Brain leaks! -
Not deleting old Brain in assignment
Dog& Dog::operator=(const Dog& other) {if (this != &other) {delete _brain; // Free old!_brain = new Brain(*other._brain); // Deep copy}return *this;}
Testing Deep Copy
Section titled “Testing Deep Copy”Dog a;Dog b = a;// Modify a's braina.getBrain()->ideas[0] = "Different idea";// b's brain should NOT changeExercise 02: Abstract Class
Section titled “Exercise 02: Abstract Class”Making Animal Abstract
Section titled “Making Animal Abstract”class Animal {public: virtual void makeSound() const = 0; // = 0 makes it pure virtual};
Animal a; // ERROR: Animal is abstractAnimal* p = new Dog(); // OKWhy Abstract?
Section titled “Why Abstract?”- “Generic animal sound” makes no sense
- Force derived classes to implement
Exercise 03: Interfaces (Materia System)
Section titled “Exercise 03: Interfaces (Materia System)”Interface Pattern
Section titled “Interface Pattern”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;};The Clone Pattern
Section titled “The Clone Pattern”class AMateria {public: virtual AMateria* clone() const = 0;};
class Ice : public AMateria {public: AMateria* clone() const { return new Ice(*this); }};Memory Management Pitfalls
Section titled “Memory Management Pitfalls”-
unequip() must NOT delete
void Character::unequip(int idx) {// Save pointer before NULLing!// Subject says: handle dropped materias as you like_inventory[idx] = NULL;} -
MateriaSource memory
- learnMateria takes ownership OR copies
- createMateria returns new instance (caller owns)
Guiding Questions
Section titled “Guiding Questions”- “What’s the difference between AMateria and ICharacter?”
- “Who owns the Materia after equip()? After unequip()?”
- “Why do we need clone()?”