Я часто сталкиваюсь с POD-структурами в коде, которые вручную инициализируются нулями memset
вот так:
struct foo;
memset(&foo, 0, sizeof(foo));
Я проверил стандарт C ++ 11 и он говорит: «Объект, инициализатором которого является пустой набор скобок, то есть (), должен быть инициализирован значением». С последующим: «Инициализировать значение [структура pod] типа T означает … объект инициализируется нулями».
Итак … это значит, что вы можете всегда безопасно сжать приведенный выше код до следующего:
struct foo{};
И иметь гарантированно инициализированную структуру, как если бы вы вызвали memset(&foo, 0, ...)
?
Если так, тогда, вообще говоря, вы можете безопасно инициализировать что-нибудь с пустыми инициализаторами вот так:
SomeUnknownType foo{}; // will 'foo' be completely "set" to known values?
Я знаю, что это не всегда возможно в C ++ 03 (раньше единый синтаксис инициализации) но возможно ли это сейчас в C ++ 11 для любого типа?
Вы можете, конечно, инициализировать любой стандартный тип макета, используя пустые скобки, и получить его инициализированным нулем. К сожалению, после добавления конструкторов в изображение это не обязательно так:
struct foo {
int f;
};
struct bar {
int b;
bar() {}
};
foo f{};
bar b{};
В то время как f.f
инициализируется нулем, b.b
неинициализирован. Однако с этим ничего не поделаешь bar
потому что ты не можешь memset()
это тоже. Это должно быть исправлено.
Memset инициализирует его до 0, но пустые скобки будут означать инициализацию вашего объекта (есть разница).
Цитирование из стандарта:
Инициализировать значение объекта типа T означает:
Кроме того, делая struct foo{};
безопасен и заботится о том, чтобы не сбрасывать указатель виртуальной таблицы.
Но делать memset(&foo, 0, sizeof(foo));
В случае виртуальных функций это действительно очень плохо, так как он сбрасывает указатель на виртуальную таблицу.