typedef struct: Инициализация по умолчанию - PullRequest
10 голосов
/ 01 июля 2010
typedef struct foo
{
    bool my_bool;
    int my_int;
} foo;

В приведенном выше примере я понимаю, что my_bool будет случайным образом инициализирован либо в true, либо в false, но как насчет my_int ? Я предполагал, что my_int будет по умолчанию инициализировано 0, но, похоже, это не так.

Определение структур таким образом несовместимо со списками инициализации, так как лучше всего инициализировать my_bool и my_int равными false и 0 соответственно?

Ответы [ 7 ]

20 голосов
/ 01 июля 2010

Типы не инициализируются. Только объекты некоторого типа инициализируются. Как и когда они инициализируются, зависит от того, как и где определен соответствующий объект. Вы не указали ни одного объекта в своем вопросе, поэтому сам по себе ваш вопрос не имеет особого смысла - в нем отсутствует необходимый контекст.

Например, если вы определяете статический объект типа foo

static foo foo_object; // zeros

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

Если вы определите автоматический объект типа foo без инициализатора, он останется неинициализированным

void func()
{
   foo foo_object; // garbage
}

Если вы определите автоматический объект типа foo с помощью агрегатного инициализатора, он будет инициализирован в соответствии с этим инициализатором

void func()
{
   foo foo_object1 = { 1, 2 }; // initialized
   foo foo_object2 = {}; // initialized with zeros
}

Если вы выделите свой объект с помощью new и не предоставите инициализатор, он останется неинициализированным

foo *p = new foo; // garbage in `*p`

Но если вы используете инициализатор (), он будет инициализирован нулем

foo *p = new foo(); // zeros in `*p`

Если вы создаете временный объект типа foo с использованием выражения foo(), результат этого выражения будет инициализирован нулем

bool b = foo().my_bool; // zero
int i = foo().my_int; // zero

Итак, еще раз, в вашем конкретном случае детали инициализации зависят от того, теперь вы создаете объект вашего типа, а не от самого вашего типа. Ваш тип сам по себе не имеет встроенных средств инициализации и никак не мешает инициализации.

11 голосов
/ 01 июля 2010

Реализация конструктора по умолчанию:

typedef struct foo 
{ 
    foo()
    : my_bool(false), my_int(0)
    {
        // Do nothing
    }
    bool my_bool; 
    int my_int; 
} foo; 
11 голосов
/ 01 июля 2010

Во-первых, способ объявления структуры в стиле C. В C ++ вы должны просто сделать:

struct foo 
{
    bool my_bool;
    int my_int;
};

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

struct foo
{
    bool my_bool{};
    bool my_int{};
};

В более старых версиях C ++ вам нужно вручную написать конструктор по умолчанию, который инициализирует все элементы (более новый синтаксис выше просто сахар для этого):

struct foo 
{
    foo() : my_bool(), my_int() { }
    bool my_bool;
    int my_int;
};

Как отмечает @sbi, если вы хотите вручную инициализировать структуру, даже без конструктора по умолчанию, вы можете сделать foo myFoo = foo();

4 голосов
/ 01 июля 2010

Есть конструктор по умолчанию:

struct foo {
    foo() : my_bool(false), my_int(0) {}
    bool my_bool;
    int  my_int;
};
2 голосов
/ 01 июля 2010

Вы не создаете любой объект в этом коде.Инициализация выполняется при создании объектов и не зависит от того, как вы объявляете структуру.

Например, следующий код инициализирует логическое значение false, а целое число - 0

foo f = { };

Обратите внимание, что вы просто typdefed вашей структуры.Вы не создали объект.Как говорили другие, вы можете опустить typedef в C ++ и просто объявить структуру, и вы все равно можете ссылаться на тип, просто сказав foo.

Если вы опускаете явную инициализацию при определении объекта, то наверняка инициализация не выполняется, если объект не определен в области пространства имен или не определен как static локально (в этом случае все члены инициализируются нулями)или класс имеет пользовательский конструктор по умолчанию, который выполняет инициализацию соответственно.

1 голос
/ 01 июля 2010

c и c ++ вообще не инициализируют переменные. Они содержат то, что было в той области памяти, в которой они находились ранее. Это также относится к переменным-членам в классах и структурах, если вы специально не инициализируете их значением.

1 голос
/ 01 июля 2010

Пока вы объявляете структуры C-way, вы можете использовать zeromemory для обнуления ровно sizeof(foo) байтов, поэтому по умолчанию все значения равны 0.

В C ++ выможет определить вашу структуру с помощью конструктора, который при необходимости установит ваши значения в некоторые значения по умолчанию.

...