Lesson 16 of 45 · C++
Lesson 23: Polymorphism and Virtual Functions
Duration: 12 min
Lesson 16 of 45 · C++
Duration: 12 min
Animal hierarchy\ncpp\nclass Animal {\npublic:\n virtual void speak() const = 0; // pure virtual\n virtual ~Animal() = default;\n};\n\nclass Dog : public Animal {\npublic:\n void speak() const override { std::cout << \"Woof!\\n\"; }\n};\n\nclass Cat : public Animal {\npublic:\n void speak() const override { std::cout << \"Meow!\\n\"; }\n};\n\nint main() {\n std::vector<std::unique_ptr<Animal>> zoo;\n zoo.emplace_back(std::make_unique<Dog>());\n zoo.emplace_back(std::make_unique<Cat>());\n for (const auto& a : zoo) {\n a->speak(); // calls the correct derived implementation\n }\n return 0;\n}\n\n\nKey points:\n- A class with at least one virtual function gets a v‑table.\n- Destructors should be virtual when deleting through a base pointer.\n- final can prevent further overriding.\n\n> Tip: Prefer non‑virtual functions for performance‑critical code. Use override to catch mistakes.\n\n---\n\n<Alert type="warning">Calling a virtual function from a base class constructor or destructor does not dispatch to the derived implementation.