У меня есть это struct
:
struct Snapshot
{
double x;
int y;
};
Я хочу x
и y
будет 0. Будут ли они по умолчанию 0 или я должен сделать:
Snapshot s = {0,0};
Каковы другие способы обнуления структуры?
У меня есть это struct
:
struct Snapshot
{
double x;
int y;
};
Я хочу x
и y
будет 0. Будут ли они по умолчанию 0 или я должен сделать:
Snapshot s = {0,0};
Каковы другие способы обнуления структуры?
Ответы:
Они не равны NULL, если вы не инициализируете структуру.
Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members
Второй обнулит все члены, первый оставляет их с неопределенными значениями. Обратите внимание, что это рекурсивно:
struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members
Второе сделает p.s.{x,y}
ноль. Вы не можете использовать эти агрегатные списки инициализаторов, если в вашей структуре есть конструкторы. Если это так, вам придется добавить правильную инициализацию для этих конструкторов
struct Snapshot {
int x;
double y;
Snapshot():x(0),y(0) { }
// other ctors / functions...
};
Инициализирует и x, и y как 0. Обратите внимание, что вы можете использовать их x(), y()
для инициализации независимо от их типа: это инициализация значения и обычно дает правильное начальное значение (0 для int, 0.0 для double, вызов конструктора по умолчанию для определенного пользователем типы, которые имеют объявленные пользователем конструкторы, ...). Это важно, особенно если ваша структура является шаблоном.
Snapshot s = {};
работать для не членов POD (для обнуления их)?
Нет, они не равны 0 по умолчанию. Самый простой способ убедиться, что все значения или значение по умолчанию равно 0, это определить конструктор
Snapshot() : x(0), y(0) {
}
Это гарантирует, что все варианты использования снимка будут иметь инициализированные значения.
В общем нет. Однако структура, объявленная как file-scope или static в функции / будет / будет инициализирована в 0 (как и все другие переменные этих областей):
int x; // 0
int y = 42; // 42
struct { int a, b; } foo; // 0, 0
void foo() {
struct { int a, b; } bar; // undefined
static struct { int c, d; } quux; // 0, 0
}
С POD вы также можете написать
Snapshot s = {};
Вы не должны использовать memset в C ++, у memset есть недостаток, заключающийся в том, что если в структуре есть не POD, он уничтожит его.
или вот так:
struct init
{
template <typename T>
operator T * ()
{
return new T();
}
};
Snapshot* s = init();
SomeType foo();
это типичное, хотя это может случиться с другими - в определения функций (в этом случае, функция, foo
которая возвращает SomeType
). Извините за некро, но если кто-нибудь еще наткнется на это, подумал, что я отвечу.
В C ++ используйте конструкторы без аргументов. В C у вас не может быть конструкторов, поэтому используйте либо memset
или - интересное решение - обозначенные инициализаторы:
struct Snapshot s = { .x = 0.0, .y = 0.0 };
Я считаю, что правильный ответ заключается в том, что их значения не определены. Часто они инициализируются в 0 при запуске отладочных версий кода. Обычно это не тот случай, когда запускаются версии выпуска.
0
в тех местах памяти. Это не то же самое, что инициализация!
Так как это POD (по сути, структура C), нет ничего плохого в том, чтобы инициализировать его способом C:
Snapshot s;
memset(&s, 0, sizeof (s));
или аналогично
Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));
Я не пошел бы так далеко, чтобы использовать calloc()
в программе C ++, хотя.
Переместите элементы pod в базовый класс, чтобы сократить список инициализаторов:
struct foo_pod
{
int x;
int y;
int z;
};
struct foo : foo_pod
{
std::string name;
foo(std::string name)
: foo_pod()
, name(name)
{
}
};
int main()
{
foo f("bar");
printf("%d %d %d %s\n", f.x, f.y, f.z, f.name.c_str());
}