Teaching Notes: Module 03
Key Learning Objectives
Section titled “Key Learning Objectives”- Inheritance basics
- Constructor/destructor chaining
- Protected vs private members
- Multiple inheritance and the diamond problem
Exercise 00: ClapTrap
Section titled “Exercise 00: ClapTrap”What It Tests
Section titled “What It Tests”- Basic class design with OCF
- Using protected for inheritance preparation
- Constructor/destructor messages
Key Values
Section titled “Key Values”| Attribute | Value |
|---|---|
| Hit points | 10 |
| Energy points | 10 |
| Attack damage | 0 |
Common Mistakes
Section titled “Common Mistakes”-
Making attributes private instead of protected
- Derived classes need access
-
Forgetting energy/HP checks
void ClapTrap::attack(const std::string& target) {if (_energyPoints <= 0 || _hitPoints <= 0) {std::cout << "ClapTrap " << _name << " can't attack!" << std::endl;return;}_energyPoints--;// ...}
Exercise 01: ScavTrap
Section titled “Exercise 01: ScavTrap”What It Tests
Section titled “What It Tests”- Basic inheritance
- Constructor chaining
- Function overriding
Key Values (Different from ClapTrap!)
Section titled “Key Values (Different from ClapTrap!)”| Attribute | Value |
|---|---|
| Hit points | 100 |
| Energy points | 50 |
| Attack damage | 20 |
Common Mistakes
Section titled “Common Mistakes”-
Not calling base constructor
// WRONGScavTrap::ScavTrap(std::string name) {_name = name; // ClapTrap not properly initialized!}// CORRECTScavTrap::ScavTrap(std::string name) : ClapTrap(name) {_hitPoints = 100;_energyPoints = 50;_attackDamage = 20;} -
Wrong construction/destruction order
- Construction: Base -> Derived
- Destruction: Derived -> Base
Guiding Questions
Section titled “Guiding Questions”- “When you create a ScavTrap, what gets constructed first?”
- “How do you initialize the ClapTrap part of a ScavTrap?”
Exercise 02: FragTrap
Section titled “Exercise 02: FragTrap”Key Values
Section titled “Key Values”| Attribute | Value |
|---|---|
| Hit points | 100 |
| Energy points | 100 |
| Attack damage | 30 |
Same inheritance pattern as ScavTrap.
Exercise 03: DiamondTrap
Section titled “Exercise 03: DiamondTrap”The Diamond Problem
Section titled “The Diamond Problem” ClapTrap / \ ScavTrap FragTrap \ / DiamondTrapWithout virtual inheritance, DiamondTrap has TWO ClapTrap subobjects!
Solution: Virtual Inheritance
Section titled “Solution: Virtual Inheritance”class ScavTrap : virtual public ClapTrap { };class FragTrap : virtual public ClapTrap { };class DiamondTrap : public ScavTrap, public FragTrap { };Common Mistakes
Section titled “Common Mistakes”-
Forgetting virtual keyword
- Must be on BOTH intermediate classes
-
Not initializing virtual base in most-derived class
DiamondTrap::DiamondTrap(std::string name): ClapTrap(name + "_clap_name"), // Virtual base initScavTrap(name),FragTrap(name),_name(name){ } -
Wrong attribute inheritance
- HP: FragTrap (100)
- Energy: ScavTrap (50)
- Damage: FragTrap (30)
- attack(): ScavTrap
Guiding Questions
Section titled “Guiding Questions”- “What happens if DiamondTrap inherits from both ScavTrap and FragTrap without virtual?”
- “Why does the most-derived class initialize the virtual base?”
- “How do you access the ClapTrap name vs DiamondTrap name?”
General Tips
Section titled “General Tips”Inheritance Visualization
Section titled “Inheritance Visualization”Draw class diagrams showing:
- What each class inherits
- Which members are overridden
- Constructor call order
Testing Construction/Destruction
Section titled “Testing Construction/Destruction”int main() { std::cout << "--- Creating ScavTrap ---" << std::endl; ScavTrap s("Scav"); std::cout << "--- End of main ---" << std::endl;}// Should show:// ClapTrap constructor// ScavTrap constructor// ScavTrap destructor// ClapTrap destructor