In the use of "placement new" it is suggested to call the cons开发者_Go百科tructor and destructor explicitly.
In this case will the objects initialized in the initializer section of a class also get properly constructed?
Same too with explicitly calling the destructor? Do the member objects get destroyed properly?
In the use of "placement new" it is suggested to call the constructor and destructor explicitly.
It's not correct to say that "you call constructor explicitly", as constructors don't have names ($12.1/1).
In this case will the objects initialized in the initializer section of a class also get properly constructed?
Yes. Why do you doubt it? Placment new only means that the new
operator will not allocate any memory, rather will use the memory which you pass in placement new, to construct the object. The object gets constructed in the memory which you pass.
Same too with explicitly calling the destructor? Do the member objects get destroyed properly?
Yes.
In the use of "placement new" it is suggested to call the constructor and destructor explicitly.
I don't think so. It will say that you need to call the destructor explicitly.
In this case will the objects initialized in the initializer section of a class also get properly constructed?
Apart from the supplying of the memory all other aspects of placement new are the same as normal new. So rather than dynamically allocating memory it just uses the supplied pointer.
Same too with explicitly calling the destructor?
You can (if you feel naught) call the destructor explicitly on any object. It will call the user defined (or compiler generated) class destructor as normal. The reason you need to explicitly do it for objects created via placement new is that you can call delete on these objects. This is because delete assumes the object was created in dynamically allocated memory and tries to re-cycle that memory after the destructor has been called.
Do the member objects get destroyed properly?
Yes.
If we think of new like this:
// not real code
template<class T> T* new(void* location = NULL) (ArgumentsForT)
{
// If you do not provide location (normal usage)
// then we allocate some memory for you.
if (location == NULL)
{ location = malloc(sizeof(T)); // Use of malloc() is just an example
}
((T*)location)->Constructor(ArgumentsForT);
return (T*)location;
}
So placement new will work just like normal new.
Looking at the call to delete
template<typename T> void delete(T* obj)
{
if (obj != NULL)
{
obj->~T();
free(obj);
}
}
The trouble here is that delete can not tell if the memory was allocated by new or if the memory was allocated by the user and passed into new (placement new). So it always calls free on the memory. If you used placement new then you may not have dynamically allocated the memory (or the memory is still being used for something else).
char x[sizeof(T)]; // don't do this (memory may not be aligned correctly).
T* obj = new (x) T();
delete obj; // FAIL. The memory was not dynamically allocated.
// Delete will try and re-claim this memory for re-yse
// Even if the memory is local.
// This is why on placement new you need to call the destructor
obj->~T();
精彩评论