0

I am interested if there is a better way to dynamically create objects from a base class pointer. Here's an example of my situation:

// I have an array of base class pointers of type square. Box is derived from square. I first create a new box object with params with new using a square pointer.


32     square * sqr_arr[10];
33     
34     square * a_square;
35     
36     a_square = new box(arr, 4, 5, 7);
37 
38     box * temp = dynamic_cast<box *>(a_square);
39 
40     sqr_arr[0] = new box(*temp);
41     
42     sqr_arr[0]->display();

My Trouble is that in my actual program I am constantly moving the pointers in the array around based on A-Z sorting, but I am having difficulty with the fact that each time I need to know which derived class I will be creating instead of the pointer "knowing" what it is pointing to and creating an object of that type.

Let's say in the code above I wanted to move sqr_arr[0] to sqr_arr[1]. Is there anyway sqr_arr[1] would be able to just make a copy with the correct use of new. In my actual program, for example, sqr_arr could create many different objects so my only solution is to iterate through with dynamic_cast of until it returns an acceptable pointer to the derive * temp.. Is this a good solution or could it be worked out in a different way?

  • In modern C++ you should almost *never* use `new` and `delete`. Instead you should be using containers and smart pointers like `std::vector`, `std::unique_ptr` and `std::shared_ptr` and functions like `std::make_unique` and `std::make_shared`. A naked `new` or (especially) naked `delete` is a *huge* red flag in any code review that comes across *my* desk. – Jesper Juhl Apr 28 '20 at 18:36
  • 1
    What you need is a polymorphic function that can make a copy of an object. I don't believe there's a way to make copy constructors polymorphic, so there's no way to do what you want automatically. – Mark Ransom Apr 28 '20 at 18:44

1 Answers1

1

You need to implement a virtual clone method in your square class that box and other derived classes can override, eg:

class square
{
public:
    virtual square* clone() = 0;
};

class box : public square
{
public:
    square* clone() override { return new box(*this); }
};

...

square* sqr_arr[10];

sqr_arr[0] = new box(arr, 4, 5, 7);
...
sqr_arr[1] = sqr_arr[0];
sqr_arr[0] = sqr_arr[1]->clone();
sqr_arr[0]->display();
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • The question specified a plain array and mentioned that there would be sorting invoked on it. That implies that you need a move or copy constructor, and there'd be no opportunity to call a `clone` function when needed. – Mark Ransom May 01 '20 at 15:55
  • @MarkRansom the OP is using an array of pointers, so such constructors are not needed just to move pointers around, and cloning will work just fine. You can't have an array of polymorphic types without using pointers, otherwise [object slicing](https://stackoverflow.com/questions/274626/) occurs. – Remy Lebeau May 01 '20 at 17:18
  • Thank you. I got around to practicing what you have suggested and it works well. Thanks again – Thunderbird May 23 '20 at 00:55
  • I found this useful in a method that needs to take one of several derived objects as a pointer to the base, copy the derived object, manipulate the base parts of the derived object and not slice the derived data members. – flyingblindonarocketcycle May 05 '22 at 14:12