Dynamic Arrays using std::vector

Storing Polymorphic Types in std::vector

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

Abstract art representing computer programming

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.

Answers to questions are automatically generated and may not have been reviewed.

3D art showing a progammer setting up a development environment
Part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, unlimited access

This course includes:

  • 59 Lessons
  • Over 200 Quiz Questions
  • 95% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved