У мене це 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};
Які ще способи зняти нульову структуру?
Відповіді:
Вони не є нульовими, якщо ви не ініціалізуєте структуру.
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 для подвійного, викликаючи конструктор за замовчуванням для визначеного користувачем типи, які мають оголошені користувачем конструктори, ...). Це важливо, особливо якщо ваша структура є шаблоном.
Snapshot s = {};
працювати для не членів ПОД (для їх обнулення)?
Ні, за замовчуванням вони не дорівнюють 0. Найпростіший спосіб переконатись у тому, що всі значення або значення за замовчуванням до 0 - це визначення конструктора
Snapshot() : x(0), y(0) {
}
Це гарантує, що для всіх застосувань Snapshot будуть ініціалізовані значення.
Загалом, ні. Однак структура, оголошена як файл-область або статична у функції / буде / буде ініціалізована до 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
в тих місцях пам'яті. Це не те саме, що ініціалізація!
Оскільки це ПОД (по суті є С-структурою), мало шкоди при його ініціалізації шляхом С:
Snapshot s;
memset(&s, 0, sizeof (s));
або аналогічно
Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));
Я б не пішов так далеко, щоб використовувати calloc()
в програмі C ++.
Перемістіть членів стручка до базового класу, щоб скоротити список ініціалізатора:
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());
}