Подтвердить что ты не робот

Typedef struct: Инициализация по умолчанию

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

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

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

4b9b3361

Ответ 1

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

Например, если вы определяете статический объект типа 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

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

Ответ 2

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

struct foo 
{
    bool my_bool;
    int my_int;
};

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

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

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

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

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

Ответ 3

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

typedef struct foo 
{ 
    foo()
    : my_bool(false), my_int(0)
    {
        // Do nothing
    }
    bool my_bool; 
    int my_int; 
} foo; 

Ответ 4

Создайте конструктор по умолчанию:

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

Ответ 5

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

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

foo f = { };

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

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

Ответ 6

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

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

Ответ 7

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