Ho questo struct:
struct Snapshot
{
double x;
int y;
};
Voglio xe yessere 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 xe yessere 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 fooche 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 memseto - 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.
0in 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());
}