Storing Polymorphic Types in std::vector

How can I store polymorphic types in a std::vector?

Storing polymorphic types in a std::vector is a common requirement when working with class hierarchies. However, it requires some special considerations due to object slicing and memory management. Let's explore how to do this correctly using pointers or smart pointers.

Using Raw Pointers

The simplest way to store polymorphic types is using raw pointers:

#include <iostream>
#include <vector>

class Character {
public:
  virtual void speak() const = 0;
  virtual ~Character() = default;
};

class Warrior : public Character {
public:
  void speak() const override{
    std::cout << "I am a warrior!\n";
  }
};

class Mage : public Character {
public:
  void speak() const override{
    std::cout << "I am a mage!\n";
  }
};

int main(){
  std::vector<Character*> characters;

  characters.push_back(new Warrior());
  characters.push_back(new Mage());

  for (const auto& character : characters) {
    character->speak();
  }

  // Don't forget to delete!
  for (auto character : characters) {
    delete character;
  }
}
I am a warrior!
I am a mage!

However, this approach requires manual memory management, which can lead to memory leaks if not handled correctly.

Using Smart Pointers

A better approach is to use smart pointers, particularly std::unique_ptr or std::shared_ptr:

#include <iostream>
#include <vector>
#include <memory>

class Character {
public:
  virtual void speak() const = 0;
  virtual ~Character() = default;
};

class Warrior : public Character {
public:
  void speak() const override{
    std::cout << "I am a warrior!\n";
  }
};

class Mage : public Character {
public:
  void speak() const override{
    std::cout << "I am a mage!\n";
  }
};

int main(){
  std::vector<std::unique_ptr<Character>>
    characters;

  characters.push_back(
    std::make_unique<Warrior>());
  characters.
    push_back(std::make_unique<Mage>());

  for (const auto& character : characters) {
    character->speak();
  }

  // No need to manually delete
}
I am a warrior!
I am a mage!

This approach is safer as it automatically manages memory, preventing leaks.

Remember, when using polymorphic types, always declare the base class destructor as virtual to ensure proper cleanup of derived classes.

By using these techniques, you can effectively store and manage polymorphic types in a std::vector, allowing for flexible and type-safe operations on collections of objects with different derived types.

Dynamic Arrays using std::vector

Explore the fundamentals of dynamic arrays with an introduction to std::vector

Questions & Answers

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

Removing Objects from std::vector
How can I remove objects from a std::vector?
Removing Elements from the Middle of a Vector
How can I efficiently remove elements from the middle of a std::vector?
Implementing a Circular Buffer with Vector
How do I implement a circular buffer using std::vector?
Using Vector with Move-Only Types
Can I use std::vector with move-only types like std::unique_ptr?
Thread Safety with std::vector
How can I safely access std::vector elements in a multithreaded environment?
Using Vector for a 2D Grid
How can I use std::vector to implement a simple 2D grid or matrix?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant