Когда конструктор вызывается явно, создаются ли инициализатор и переменные-члены? - PullRequest
0 голосов
/ 07 января 2011

При использовании «размещения нового» предлагается явно вызывать конструктор и деструктор.

В этом случае объекты, инициализированные в секции инициализатора класса, также будут правильно построены?

То же самое и с явным вызовом деструктора? Правильно ли уничтожены объекты-члены?

Ответы [ 2 ]

2 голосов
/ 07 января 2011

При использовании «размещения новых» это предложил вызвать конструктор и деструктор явно.

Неправильно говорить, что «вы вызываете конструктор явно », так как конструкторы не имеют имен ($ 12.1 / 1).

В этом случае будут объекты инициализируется в разделе инициализатора класса также получить должным образом построен?

Да. Почему вы сомневаетесь в этом? Только размещение нового означает, что оператор new не будет выделять какую-либо память, скорее будет использовать память, которую вы передадите при размещении нового, для создания объекта. Объект создается в памяти, которую вы передаете.

То же самое с явным вызовом деструктор? Получают ли объекты-члены уничтожен правильно?

Да.

1 голос
/ 07 января 2011

При использовании «размещения нового» предлагается явно вызывать конструктор и деструктор.

Я так не думаю. Он скажет, что вам нужно явно вызвать деструктор.

В этом случае объекты, инициализированные в секции инициализатора класса, также будут правильно построены?

Помимо предоставления памяти, все остальные аспекты размещения new такие же, как обычные new. Поэтому вместо динамического выделения памяти он просто использует предоставленный указатель.

То же самое и с явным вызовом деструктора?

Вы можете (если вы ничего не чувствуете) явно вызывать деструктор для любого объекта. Он будет вызывать пользовательский (или сгенерированный компилятором) деструктор класса как обычно. Причина, по которой вам нужно явно сделать это для объектов, созданных с помощью размещения new, заключается в том, что вы можете вызвать delete для этих объектов. Это связано с тем, что delete предполагает, что объект был создан в динамически выделенной памяти, и пытается повторно выполнить эту память после вызова деструктора.

Правильно ли уничтожены объекты-члены?

Да.

Если мы думаем о новом, как это:

// 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;
}

Таким образом, размещение нового будет работать так же, как обычное новое.
Глядя на звонок для удаления

template<typename T> void delete(T* obj)
{
    if (obj != NULL)
    {
        obj->~T();
        free(obj);
    }
}

Проблема здесь в том, что delete не может определить, была ли память выделена новой или была ли выделена память пользователем и передана в новую (размещение новой). Так что это всегда звонит бесплатно в память. Если вы использовали новое размещение, то у вас может не быть динамического выделения памяти (или память все еще используется для чего-то другого).

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();
...