Одна вещь, которую нужно осознать, это то, что «инициализация значения» является новой для стандарта 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 <stdio.h>
#include <string.h>
#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)];
memset( buf, 0x5a, sizeof( buf));
// use placement new on the memset'ed buffer to make sure
// if we see a zero result it's 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
printf( "m is %d\n", pB->m);
return 0;
}