0

In the use of "placement new" it is suggested to call the constructor 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?

JeffV
  • 52,985
  • 32
  • 103
  • 124
  • ` it is suggested to call the constructor and destructor explicitly`.How can you call constructor explicitly ? – Mahesh Jan 07 '11 at 14:58
  • @Mahesh, `void* const pmem = malloc(sizeof(test)); test* const t = new((void*)pmem) test();` and for the dtor: `t->~test();`. – Moo-Juice Jan 07 '11 at 15:17
  • @ MJ - AFAIK you can call the destructor but `explicit` should never be used for constructor. Though while in initializer lists, it seems you are calling the baseclass constructor from its derived class. If the keyword `explicit` is used, then I should be able to do `obj->foo()` if `foo` is the class name. But that is not allowed. Am I correct ? – Mahesh Jan 07 '11 at 15:40
  • 1
    @ Moo-Juice: If that is the definition of explicit, then the constructor is **always** called explicitly. Generally we think of the constructor has being called implicitly during object construction (as the constructor does not have an actual name). The destructor can be explicitly called. – Martin York Jan 07 '11 at 15:41
  • The constructor is not called explicitly when creating an array of objects. – JeffV Jan 07 '11 at 17:41

2 Answers2

2

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.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
1

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();
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • +1 for better elaborated answer. I think the questioner should pick this as his accepted answer, instead of mine :-) – Nawaz Jan 07 '11 at 16:01