I have used initialization lists a great deal in my C++ programs but wasn't aware that you could allocate memory within them.
So you can do something (as a contrived example) like this:
class Test { private: int* i; int* j; int count; int* k; public: Test(void) : i(new int), j(new int[10]), count(10), k(new int[count]) { } ~Test(void) { delete i; delete [] j; delete [] k; } };
Are there any issues in doing memory allocation in this way? Regarding the order of initialization here is it safe to have a parameter initialized by one initialized in the same list? i.e. as I allocate count
before I use it is it safe to use or is there some special initialization order I could fall foul of?
A constructor does not allocate memory for the class object its this pointer refers to, but may allocate storage for more objects than its class object refers to. If memory allocation is required for objects, constructors can explicitly call the new operator.
Should my constructors use “initialization lists” or “assignment”? ¶ Δ Initialization lists. In fact, constructors should initialize as a rule all member objects in the initialization list.
Problem of initialization in C++ These data members have no explicitly defined scope thus they are private by default. The private data members cannot be initialized later using the object of the class. Here, if the data members are initialized using the object of the class, then it will show an error.
Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class.
It's not exception-safe. If the new
for j
throws an exception then the destructor for Test
is not called, and so the memory for i
is not freed.
The destructor of i
is called if the initializer for j
throws, it's just that a raw pointer has no destructor. So you could make it exception-safe by replacing i
with a suitable smart pointer. In this case, unique_ptr<int>
for i
and unique_ptr<int[]>
for j
would do.
You can rely on the initializers to be executed in their correct order (the order the members are defined, not necessarily the order in the list). They can safely use data members that have already been initialized, so there's no problem with using count
in the initializer for k
.
This code could leak memory in the presence of an initializer that throws an exception.
Note that this could be made to work correctly if the members of Test
were smart -- rather than raw -- pointers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With