Search code examples
c++arraysabstract-class

How to implement arrays of abstract classes in C++?


My use case is the following. I have a pure abstract class and inherited classes like so:

class AbstractCell {
public:
   // data members
   virtual void fn () = 0;  // pure virtual functions
}

class DerivedCell1 : public AbstractCell {
public:
  // more data members
  void fn () {}  // implementation of all virtual functions
}

class DerivedCell2 : public AbstractCell {
public:
  // more data members
  void fn () {}  // implementation of all virtual functions
}

Now, I want to create an array of the abstract class as a member of another class.

class AbstractGrid {
public:
  AbstractCell m_cells [10][10];  //  this is illegal
  
  void printCells() {
      // accesses and prints m_cells
      // only uses members of AbstractCell
  }
}

class DerivedGrid1 : public AbstractCell {
public:
  DerivedCell1 m_cells [10][10];  // I want this class to use DerivedCell1 instead of AbstractCell
}

class DerivedGrid2 : public AbstractCell {
public:
  DerivedCell2 m_cells [10][10];  // I want this class to use DerivedCell2 instead of AbstractCell
}

How should I go about achieving this?

Constraints:

  1. For runtime efficiency, I want to use fixed-size arrays and not dynamic memory allocation (new or smart pointers).
  2. I want a solution other than using template classes.

I'm currently using templates, but I'm wondering if there's a better way.


Solution

  • Abstract classes rely on virtual functions to be useful. The right function to be called is determined at runtime depending on the real type of the polymorphic object.

    You cannot benefit of such polymorphism with an array of objects. Arrays require a type that is determined at compile-time and that can be instantiated. This is incompatible with abstract classes.

    If you want an array with abstract classes, you have to go for an array of pointers. And typically, you'd use unique_ptr or shared_ptr, to avoid accidents in memory management. You can use new/delete if you prefer, but at your own risk.

    If you love templates and are worried about performance of dynamic memory allocation, you may have a look at Alexandrescu's Modern C++ design.