-1

I have an abstract base class called CBase and two other classes CDerived1 and CDerived2 that are derived from CBase.

How would I now create a dynamic array (i.e. add and delete elements at runtime) of CBase? Of course, this array would just contain objects of the derived classes because the base class is abstract.

I would try something like this:

CBase* arr;
arr = (CBase*) malloc(arrSize*sizeof(CBase));

It feels like this solution would get complicated when I want to resize the array as I want. How would I do that? Or do you recommend any other kind of array for that?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • (a) manual dynamic memory management in modern C++ = terrible idea. (b) using `malloc` to accomplish (a) even *more* terrible idea. Use an appropriate container of smart pointers. – WhozCraig May 23 '19 at 00:28
  • There is so much wrong with this. I would highly recommend you get a [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) and read it very carefully. – alter_igel May 23 '19 at 00:57
  • 1) You're using `malloc` when `new` is much better (malloc does not call c'tors). 2) You're using manual memory management when standard containers or `unique_ptr` are much better 3) You cannot have an array of polymorphic objects. That will lead to object slicing. You need another level of indirection. – alter_igel May 23 '19 at 01:00
  • 1
    I believe the tool you should be reaching for is `vector>`. – alter_igel May 23 '19 at 01:00

1 Answers1

1

You are allocating an array of CBase objects, so it will suffer from object slicing when you try to assign derived objects to the array elements. What you really need is an array of CBase* pointers instead:

CBase** arr;
arr = new CBase*[arrSize];

arr[0] = new CDerived1;
...

for (int i = 0; i < arrSize; ++i)
    delete arr[i];
delete [] arr;

That being said, you really should use std::vector instead of new[], and in C++11 and later, prefer std::unique_ptr instead of raw pointers:

#include <vector>
#include <memory>

std::vector<std::unique_ptr<CBase>> arr;
arr.reserve(arrSize);

arr.push_back(std::unique_ptr<CBase>(new CDerived1));
// or, in C++14 and later:
// arr.push_back(std::make_unique<CDerived1>());
...

//no manual cleanup needed!
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770