Ответ 1
Необходимо понять, что "инициализация значения" является новой для стандарта C++ 2003 года - его нет в первоначальном стандарте 1998 года (я думаю, что это может быть единственное отличие, которое больше, чем пояснение). См. Ответ Кирилла В. Лядвинского на определения прямо из стандарта.
Посмотрите этот предыдущий ответ о поведении operator new
для деталей о различном поведении этого типа инициализации и когда они запускаются (и когда они отличаются от C++ 98 до C++ 03):
Суть ответа такова:
Иногда память, возвращаемая оператором new, будет инициализирована, и иногда это не будет зависеть от того, является ли тип, который вы обновляете, POD, или это класс, который содержит члены POD и использует сгенерированный компилятором конструктор по умолчанию,
- В C++ 1998 есть 2 типа инициализации: ноль и по умолчанию
- В C++ 2003 был добавлен третий тип инициализации, инициализация значения.
По меньшей мере, это довольно сложно, и когда различные методы применяются тонко.
Обязательно нужно знать, что MSVC следует правилам C++ 98 даже в VS 2008 (VC 9 или cl.exe версии 15.x).
Следующий фрагмент показывает, что MSVC и Digital Mars следуют правилам C++ 98, в то время как GCC 3.4.5 и Comeau следуют правилам C++ 03:
#include <cstdio>
#include <cstring>
#include <new>
struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m
int main()
{
char buf[sizeof(B)];
std::memset( buf, 0x5a, sizeof( buf));
// use placement new on the memset'ed buffer to make sure
// if we see a zero result it due to an explicit
// value initialization
B* pB = new(buf) B(); //C++98 rules - pB->m is uninitialized
//C++03 rules - pB->m is set to 0
std::printf( "m is %d\n", pB->m);
return 0;
}