Ho questo struct
:
struct Snapshot
{
double x;
int y;
};
Voglio x
e y
essere 0. Saranno 0 per impostazione predefinita o devo fare:
Snapshot s = {0,0};
Quali sono gli altri modi per azzerare la struttura?
Ho questo struct
:
struct Snapshot
{
double x;
int y;
};
Voglio x
e y
essere 0. Saranno 0 per impostazione predefinita o devo fare:
Snapshot s = {0,0};
Quali sono gli altri modi per azzerare la struttura?
Risposte:
Non sono nulli se non si inizializza la struttura.
Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members
Il secondo renderà zero tutti i membri, il primo li lascerà a valori non specificati. Si noti che è ricorsivo:
struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members
Il secondo farà p.s.{x,y}
zero. Non puoi usare questi elenchi di inizializzatori aggregati se hai costruttori nella tua struttura. In tal caso, dovrai aggiungere una corretta inizializzazione a quei costruttori
struct Snapshot {
int x;
double y;
Snapshot():x(0),y(0) { }
// other ctors / functions...
};
Inizializzerà sia x che y su 0. Si noti che è possibile utilizzare x(), y()
per inizializzarli ignorando il loro tipo: Questo è quindi l'inizializzazione del valore e di solito produce un valore iniziale corretto (0 per int, 0,0 per doppio, chiamando il costruttore predefinito per l'utente definito tipi con costruttori dichiarati dall'utente, ...). Questo è importante soprattutto se la tua struttura è un modello.
Snapshot s = {};
per i membri non POD (per azzerarli)?
No, non sono 0 per impostazione predefinita. Il modo più semplice per garantire che tutti i valori o il valore predefinito siano 0 è definire un costruttore
Snapshot() : x(0), y(0) {
}
Ciò garantisce che tutti gli usi di Snapshot abbiano valori inizializzati.
In generale, no. Tuttavia, una struttura dichiarata come ambito di file o statica in una funzione / verrà / verrà inizializzata su 0 (proprio come tutte le altre variabili di tali ambiti):
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
}
Con POD puoi anche scrivere
Snapshot s = {};
Non dovresti usare memset in C ++, memset ha lo svantaggio che se c'è un non-POD nella struttura lo distruggerà.
o in questo modo:
struct init
{
template <typename T>
operator T * ()
{
return new T();
}
};
Snapshot* s = init();
SomeType foo();
è quella tipica, sebbene possa accadere con gli altri - in definizioni di funzioni (in quel caso, una funzione foo
che ritorna SomeType
). Ci scusiamo per il necro, ma se qualcun altro si imbatte in questo, ho pensato che avrei risposto.
In C ++, utilizzare i costruttori senza argomento. In C non puoi avere costruttori, quindi usa uno memset
o - la soluzione interessante - inizializzatori designati:
struct Snapshot s = { .x = 0.0, .y = 0.0 };
Credo che la risposta corretta sia che i loro valori non sono definiti. Spesso vengono inizializzati su 0 quando si eseguono versioni di debug del codice. Questo di solito non è il caso quando si eseguono versioni di rilascio.
0
in quei posti in memoria. Questo non è lo stesso dell'inizializzazione!
Dato che si tratta di un POD (essenzialmente una struttura in C), l'inizializzazione in modo C presenta pochi danni:
Snapshot s;
memset(&s, 0, sizeof (s));
o similmente
Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));
Non andrei così lontano da usare calloc()
in un programma C ++.
Sposta i membri del pod in una classe base per abbreviare l'elenco di inizializzatori:
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());
}