References and Runtime Polymorphism

Can I use references with polymorphic classes to achieve runtime polymorphism?

Absolutely! References are a great way to achieve runtime polymorphism in C++. They allow you to work with derived class objects through base class references, enabling you to call virtual functions and get the correct derived class behavior.

Let's look at an example using our Character class from the lesson:

#include <iostream>
#include <string>

class Character {
 public:
  Character(const std::string& name)
  : mName{name} {}
  virtual void Attack() const {
    std::cout << mName
      << " performs a basic attack!\n";
  }
  virtual ~Character() = default;

 protected:
  std::string mName;
};

class Warrior : public Character {
 public:
  Warrior(const std::string& name)
  : Character{name} {}
  void Attack() const override {
    std::cout << mName
      << " swings a mighty sword!\n";
  }
};

class Mage : public Character {
 public:
  Mage(const std::string& name)
  : Character{name} {}
  void Attack() const override {
    std::cout << mName
      << " casts a powerful spell!\n";
  }
};

void PerformAttack(const Character& character) {
  character.Attack();
}

int main() {
  Character genericChar{"Generic"};
  Warrior warrior{"Conan"};
  Mage mage{"Gandalf"};

  PerformAttack(genericChar);
  PerformAttack(warrior);
  PerformAttack(mage);
}
Generic performs a basic attack!
Conan swings a mighty sword!
Gandalf casts a powerful spell!

In this example:

  1. We define a base Character class with a virtual Attack() method.
  2. We create two derived classes, Warrior and Mage, each overriding the Attack() method.
  3. We define a PerformAttack() function that takes a const Character& parameter.
  4. In main(), we create instances of each class and pass them to PerformAttack().

The key here is the PerformAttack() function. It takes a reference to a Character, but when we call it with a Warrior or Mage, it still calls the correct overridden Attack() method. This is runtime polymorphism in action!

A few important points:

  • The Attack() method must be declared virtual in the base class for this to work.
  • We use const references here as we're not modifying the objects.
  • It's good practice to declare a virtual destructor in the base class when using polymorphism.

References provide a clean syntax for achieving polymorphism, as you don't need to worry about dereferencing pointers. However, remember that unlike pointers, references can't be null and can't be reassigned after initialization.

References

This lesson introduces references, explaining how they work, their benefits, and their role in performance and data manipulation

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Swapping Values Using References
How can I use references to swap the values of two variables without using a temporary variable?
Creating an Array of References
Is it possible to create an array of references in C++?
Implementing Observer Pattern with References
How can I use references to implement a simple observer pattern in C++?
Reference vs Pointer to Const
What's the difference between a reference and a pointer to const in terms of function parameters?
Dangers of Returning References to Local Objects
What are the implications of returning a reference from a function that creates a local object?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant