2013-05-28 3 views
36

Если мне нужно инициализировать только несколько избранных значений в структуры C++, это было бы правильно:Инициализация значений по умолчанию в структуры

struct foo { 
    foo() : a(true), b(true) {} 
    bool a; 
    bool b; 
    bool c; 
} bar; 

Я правильно предположить, что я бы в конечном итоге с одной struct пункта под названием bar с элементами bar.a = true, bar.b = true и не определено bar.c?

+0

Бар - это просто переименование, если вы используете C++, вам не нужно так поступать – aaronman

+10

@aaronman no, 'bar' - это переменная. –

+5

@aaronman Я думаю, вы запутываете это с помощью 'typedef struct foo {} bar;'. – greatwolf

ответ

22

Да. bar.a и bar.b установлены в true, но bar.c не определено. Однако определенный компилятор установит значение false.

Смотрите живой пример здесь: struct demo

Согласно стандарту языка Си ++ Раздел 8.5.12:

если инициализация не выполняется, объект с автоматической или динамической продолжительности хранения имеет неопределенную величину

Для примитивных встроенных типов данных (bool, char, wchar_t, short, int, long, float, double, long d ouble), только глобальные переменные (все статические переменные хранилища) получают значение по умолчанию, равное нулю, если они явно не инициализированы.

Если вы действительно не хотите, чтобы не определено bar.c, вы должны также инициализировать его так же, как и для bar.a и bar.b.

+0

Раздел и параграф? –

+1

@CaptainObvlious только что обновил, жаль, что меня отвлекало другое, а не компьютер. – taocp

+2

Это не «неопределенный», он _uninitialized_, то есть имеет значение _ndeterminate_. –

5

Вы можете сделать это с помощью конструктора, например:

struct Date 
{ 
int day; 
int month; 
int year; 

Date() 
{ 
    day=0; 
    month=0; 
    year=0; 
} 
}; 

или как это:

struct Date 
{ 
int day; 
int month; 
int year; 

Date():day(0), 
     month(0), 
     year(0){} 
}; 

В вашем случае bar.c не определено, и его значение зависит от компилятора (а для a и b установлено значение true).

+7

Нет причин предпочитать первую форму. Вы должны использовать списки инициализации. – jamesdlin

+0

@jamesdlin согласился в 99,9% случаев, где второй значительно предпочтительнее по бесчисленным причинам. однако - просто играть адвоката дьявола!- если вместо 'int' членов были пользовательские классы, которые должны были соответствовать определению тривиального (например, никакого конструктора, отличного от стандартного), это было бы причиной для назначения в теле вместо создания в списке инициализации. однако число сценариев, в которых это полезно, по-видимому, является крошечным меньшинством, поэтому списки списков обязательно должны быть рекомендацией по умолчанию - за редким исключением, в отличие от этого, были тщательно определены и оправданы. –

+0

@underscore_d Нет, это не было бы такой причиной. Вы можете использовать списки инициализации во всех случаях, кроме случаев, когда переменные-члены являются взаимозависимыми, и это является нарушением 3NF ;-) – EJP

131

Вам даже не нужно определить конструктор

struct foo { 
    bool a = true; 
    bool b = true; 
    bool c; 
} bar; 

уточнить: они называются фигурными скобки или равно-инициализаторы (потому что вы можете также использовать инициализацию скобки вместо знака равенства). Это не только для агрегатов: вы можете использовать это в обычных определениях классов. Это было добавлено в C++ 11.

+0

@Erik, как вы можете инициализировать элементы структуры в декларации. Не допускается. – Daemon

+0

Этот тип инициализации возможен с C#, я думаю, но определенно не с C++ или C. – dreamlax

+85

Downvoters: Пожалуйста, ознакомьтесь с обновлениями C++ 11 стандарта, прежде чем читать лекции людям о том, что является или не является законным. [Он действительно компилируется просто отлично.] (Http://ideone.com/lmYeem) Это C++ 11, а C++ 11 * - это * C++, пока не будет принята новая версия. –

Смежные вопросы