The following code is just used to illustrate my question.
template<class T>
class array<T>
{
public:
// constructor
array(cap = 10):capacity(cap)
{element = new T [capacity]; size =0;}
// destructor
~array(){delete [] element;}
void erase(int i);
private:
T *element;
int capacity;
int size;
};
template<class T>
void class array<T>::erase(int i){
// copy
// destruct object
element[i].~T(); ////
// other codes
}
If I have array<string> arr
in main.cpp. When I use erase(5)
, the object of element[5]
is destroyed but the space of element[5]
will not be deallocated, can I just use element[5] = "abc"
to put a new value here? or should I have to use placement new to put new value in the space of element [5]
?
When program ends, the arr<string>
will call its own destructor which also calls delete [] element
. So the destructor of string will run to destroy the object first and then free the space. But since I have explicitly destruct the element[5]
, does that matter the destructor (which is called by the arr's destuctor) run twice to destruct element[5]
? I know the space can not be deallocated twice, how about the object? I made some tests and found it seems fine if I just destruct object twice instead of deallocating space twice.
Update
The answers are:
(1)I have to use placement new if I explicitly call destructor.
(2) repeatedly destructing object is defined as undefined behavior which may be accepted in most systems but should try to avoid this practice.
You need to use the placement-new syntax:
new (element + 5) string("abc");
It would be incorrect to say element[5] = "abc"
; this would invoke operator=
on element[5]
, which is not a valid object, yielding undefined behavior.
When program ends, the
arr<string>
will call its own destructor which also callsdelete [] element
.
This is wrong: you are going to end up calling the destructor for objects whose destructors have already been called (e.g., elements[5]
in the aforementioned example). This also yields undefined behavior.
Consider using the std::allocator
and its interface. It allows you easily to separate allocation from construction. It is used by the C++ Standard Library containers.
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