Що означають наступні фрази в C ++:
нульова ініціалізація,
ініціалізація за замовчуванням та
ініціалізація значення
Що повинен знати про них розробник C ++?
Що означають наступні фрази в C ++:
нульова ініціалізація,
ініціалізація за замовчуванням та
ініціалізація значення
Що повинен знати про них розробник C ++?
Відповіді:
Слід усвідомити, що "ініціалізація значення" є новою зі стандартом C ++ 2003 - її немає в оригінальному стандарті 1998 року (я думаю, це може бути єдиною різницею, що є більш ніж уточненням). Дивіться відповідь Кирила В. Лядвінського щодо визначень прямо зі стандарту.
Дивіться цю попередню відповідь про поведінку operator new
для деталей щодо різної поведінки цього типу ініціалізації та коли вони починаються (і коли вони відрізняються від c ++ 98 до C ++ 03):
Основний пункт відповіді:
Іноді пам’ять, повернута новим оператором, буде ініціалізована, а іноді вона не залежатиме від того, тип ви нововведення - це POD, або якщо це клас, який містить членів POD і використовує створений компілятором конструктор за замовчуванням .
- У C ++ 1998 є 2 типи ініціалізації: нуль та за замовчуванням
- У C ++ 2003 був доданий 3-й тип ініціалізації, значення ініціалізації.
Як мінімум сказати, це досить складно, і коли різні методи стають тонкими.
Слід пам’ятати одне, що 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'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
std::printf( "m is %d\n", pB->m);
return 0;
}
int
, але m()
на третьому рядку значення ініціалізує m. Важливо, якщо ви переходите int m;
на B m;
. :)
A
і C
не використовуються в цьому прикладі (вони переносяться з іншої пов'язаної відповіді). Навіть незважаючи на те, що C ++ 98 та C ++ 03 використовують різні термінології, коли описують, як A
і C
як будуються, результат є однаковим в обох стандартах. struct B
Результатом є лише інша поведінка.
struct C { C() : m() {}; ~C(); B m; };
, то у вас буде m.m
0. Але якщо це буде ініціалізація за замовчуванням, m
як ви кажете C ++ 03, m.m
це не буде ініціалізовано, як у C ++ 98.
C ++ 03 Стандарт 8.5 / 5:
Для того, щоб нуль-ініціалізації об'єкта типу Т означає:
- якщо Т являє собою тип скаляр (3.9), то об'єкт встановлюється в значення 0 (нуль) перетворюється в T;
- якщо T - несоюзний тип класу, кожен нестатичний член даних і кожен суб'єкт базового класу нульово ініціалізується;
- якщо T - тип об'єднання, перший іменований член даних об'єкта ініціалізується нулем;
- якщо T - тип масиву, кожен елемент нульово ініціалізується;
- якщо T - еталонний тип, ініціалізація не проводиться.Під ініціалізацією за замовчуванням об’єкта типу T означає:
- якщо T - тип класу, який не є POD (пункт 9), конструктор за замовчуванням для T викликається (і ініціалізація неправильно сформована, якщо T не має доступного конструктора за замовчуванням);
- якщо T - тип масиву, кожен елемент ініціалізується за замовчуванням;
- в іншому випадку об'єкт ініціалізується нулем.Для того, щоб значення ініціалізації об'єкта типу Т означає:
- якщо Т типу класу (пункт 9) з користувачем оголошено конструктором (12.1), то конструктор за замовчуванням для Т називається (і ініціалізація погано формується , якщо Т не має доступного конструктора за замовчуванням);
- якщо T - несоюзний тип класу без оголошеного користувачем конструктора, то кожен нестатичний член даних і компонент базового класу T ініціалізується за значенням;
- якщо T - тип масиву, то кожен елемент ініціалізується за значенням;
- в іншому випадку об'єкт ініціалізується нулемПрограма, яка вимагає ініціалізації за замовчуванням або ініціалізації значення об'єкта еталонного типу, неправильно сформована. Якщо T - тип cv-кваліфікації, для цих визначень нульової ініціалізації, ініціалізації за замовчуванням та ініціалізації значень використовується версія cv-некваліфікована версія T.