class Staff{
public:
Staff();
Staff * list;
};
int main(){
Staff * personnel = new Staff();
return 0;
}
Staff::Staff(){
int size = 1;
list = new Staff[size];
}
The error is when in the constructor I reserve the space for the staff list, and I get a exited segmentation fault
. I do it that way so I can later add other child classes to that list. How should I declare that list?
One thing is a class and another a list of objects. In the same way, you should have two classes instead of just one: The one that represents the object itself and another one to manage the list:
It is very important to provide simple responsibilities to each element. If a class has to manage data, and also a list, and also interact with the file system, and also... it ends up becoming a titanic monster that you won't be able to tame.
It is easier and more comfortable to manage, on the one hand, all the information about the personnel (class
Staff
) and, on the other hand, to manage a possible list of objects.As long as you use pointers you should have no problems in this regard. If you have studied how polymorphism works, you will know that a base class pointer is capable of handling derived class pointers:
Now, where your design fails is that you're making use of a simple pointer. If you only want to store an object you will not have a problem, as you have seen in the example above these lines.
But when you try to point to a collection of objects you will see that it is impossible for you to store objects of different types.
Cast?
To understand the problem you have to see how memory is managed. When you call
new[]
the Operating System, it provides you with a memory region where X objects of type Y enter:Namely:
Notice that all the elements have exactly the same size.
On the other hand, we have that derived classes can (and often do) have more member variables, which makes the objects of these derived classes take up more memory:
As you can see, in a hole of size X you cannot fit an object of size Y if Y>X
To solve this and other problems that I will not explain so as not to lengthen myself too much, you have to use a double pointer:
In this way, what we do is reserve memory to store X pointers to objects of type
Staff
:As it happens, pointers are variables that all occupy exactly the same thing regardless of their specific type:
Thus, when using a double pointer, what you get is to have space to store pointers... regardless of their specific type since they all occupy the same amount. The only requirement is that the pointers must be compatible (class inheritance):
Now, to populate the list, you simply have to create objects of the type you want:
Your problem is very simple: the instruction
causes an infinite recursive call to the constructor itself, thus running out of memory on your system. Notice that, inside the constructor itself, you do
The
operator new
in array calls the default constructor, thus entering the constructor. Which calls back tonew
. With which you go back into the constructor, which calls againnew
... Thus the recursion begins, and it never ends.One possible solution is to not allocate memory in the constructor:
With which you would no longer have that problem ... it consists of checking, every time you need it, that the member-variable
personnel
has been initialized.Which you can do very easily, by adding a getter to get the value of your variable: