My task specifically states that I have to create a random array of Squares and Triangles, that are inherited from an abstract class Figure, and then I have to print out the
Firstly main
must return int
. Then you need to create an array of pointers which will show to abstract class Figure
.
Figure **dyn_arr = new Figure*[size];
Then if you want to add a new object of the derived class you are adding simply like this.
dyn_arr[0] = new Triangle();
--> this will create new object which will return the address of that object, and your array is actually array of pointers.
Finnaly if you want to call the function square
from any class you can do that like this.
dyn_arr[0]->square();
p.s. If you don't have at least a little experience with pointers this can be confusing.
You can create a list of generated functions to select from, to create dynamically allocated objects. Using a rng you can then randomly select from the list of generated functions to call, in order to fill out an array of unique_ptr<Figure>
s.
Example using std::deque
instead of std::vector
:
template<typename T>
Figure* Create() { return new T(); }
std::function<Figure*(void)> createFunctions [] = {
Create<Square>
,Create<Triangle>
};
int main()
{
std::deque<std::unique_ptr<Figure>> shapes;
std::mt19937 rng;
rng.seed(std::random_device()());
std::uniform_int_distribution<std::mt19937::result_type> idxSel(0,1);
for(int i = 0; i < 20; ++i)
{
shapes.emplace_back(createFunctions[idxSel(rng)]());
}
}
Figure *dyn_arr = new Figure[size]; // this doesn't work
It doesn't work because we cannot create an array of Figure
s because of the pure virtual function. We wouldn't want to create a Figure
by itself in any case. We only want to create either a Square
or a Triangle
and their sizes may differ. So there is no way to allocate the memory when the array is created.
You could create an array of pointers (size is known at compile time) and then iterate over that:
auto dyn_arr = new Figure*[size];
// auto in the above context becomes Figure** (pointer to a pointer)
for(int i = 0; i < size; i++)
cout << dyn_arr[i]->square();
Please keep in mind that arrays and pointers used this way is prone to errors. Far better to use std::make_unique and std::vector.
Here is one way to randomly create the objects:
Figure* go_figure()
{
std::uniform_int_distribution<int> ud{0,1};
static std::random_device rd{};
switch(ud(rd))
{
case 0: return new Square{};
case 1: return new Triangle{};
}
}
int main()
{
int size = 20;
auto dyn_arr = new Figure*[size];
for(int i = 0; i < size; i++)
dyn_arr[i] = go_figure();
for(int i = 0; i < size; i++)
cout << dyn_arr[i]->square();
for(int i = 0; i < size; i++)
delete dyn_arr[i];
delete[] dyn_arr;
}