Mam to struct:
struct Snapshot
{
double x;
int y;
};
Chcę xi ybędę wynosić 0. Czy będą domyślnie wynosić 0 czy czy muszę zrobić:
Snapshot s = {0,0};
Jakie są inne sposoby wyzerowania struktury?
Mam to struct:
struct Snapshot
{
double x;
int y;
};
Chcę xi ybędę wynosić 0. Czy będą domyślnie wynosić 0 czy czy muszę zrobić:
Snapshot s = {0,0};
Jakie są inne sposoby wyzerowania struktury?
Odpowiedzi:
Nie są zerowe, jeśli nie zainicjujesz struktury.
Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members
Drugi spowoduje, że wszyscy członkowie będą zero, pierwszy pozostawi ich na nieokreślonych wartościach. Pamiętaj, że jest rekurencyjny:
struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members
Drugi spowoduje p.s.{x,y}zero. Nie możesz używać tych zagregowanych list inicjalizacyjnych, jeśli masz w swoim konstruktorze konstruktory. W takim przypadku konieczne będzie dodanie odpowiedniej inicjalizacji do tych konstruktorów
struct Snapshot {
int x;
double y;
Snapshot():x(0),y(0) { }
// other ctors / functions...
};
Zainicjuje zarówno x, jak i y do 0. Zauważ, że możesz użyć x(), y()do zainicjowania ich bez względu na ich typ: To jest następnie inicjalizacja wartości i zwykle daje prawidłową wartość początkową (0 dla int, 0,0 dla podwójnego, wywoływanie domyślnego konstruktora dla zdefiniowanego przez użytkownika typy, które mają zadeklarowane przez użytkownika konstruktory, ...). Jest to ważne, zwłaszcza jeśli twój struct jest szablonem.
Snapshot s = {};działał dla członków spoza POD (do ich zerowania)?
Nie, domyślnie nie są to 0. Najprostszym sposobem upewnienia się, że wszystkie wartości lub domyślnie 0 to zdefiniowanie konstruktora
Snapshot() : x(0), y(0) {
}
Zapewnia to, że wszystkie zastosowania migawki będą miały zainicjowane wartości.
Ogólnie nie. Jednak struktura zadeklarowana jako zakres pliku lub statyczna w funkcji / will / zostanie zainicjowana na 0 (podobnie jak wszystkie inne zmienne tych zakresów):
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
}
Z POD możesz także pisać
Snapshot s = {};
Nie powinieneś używać memset w C ++, memset ma tę wadę, że jeśli w strukturze nie ma POD, to go zniszczy.
lub tak:
struct init
{
template <typename T>
operator T * ()
{
return new T();
}
};
Snapshot* s = init();
SomeType foo();jest typowy, choć może się zdarzyć z innymi - w definicje funkcji (w takim przypadku funkcja, fooktóra zwraca SomeType). Przepraszam za nekro, ale jeśli ktokolwiek natknie się na to, pomyślałem, że odpowiem.
W C ++ użyj konstruktorów bez argumentów. W C nie możesz mieć konstruktorów, więc użyj jednego memsetlub - ciekawe rozwiązanie - wyznaczonych inicjatorów:
struct Snapshot s = { .x = 0.0, .y = 0.0 };
Uważam, że poprawną odpowiedzią jest to, że ich wartości są niezdefiniowane. Często są one inicjowane na 0 podczas uruchamiania debugowanych wersji kodu. Zwykle nie dzieje się tak podczas uruchamiania wersji.
0w tych miejscach w pamięci. To nie to samo, co inicjalizacja!
Ponieważ jest to POD (zasadniczo struktura C), inicjowanie go w sposób C ma niewielką szkodę:
Snapshot s;
memset(&s, 0, sizeof (s));
lub podobnie
Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));
Nie posunąłbym się jednak tak daleko, aby użyć go calloc()w programie C ++.
Przenieś członków kapsuły do klasy podstawowej, aby skrócić listę inicjalizują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());
}