J'ai ceci struct
:
struct Snapshot
{
double x;
int y;
};
Je veux x
et y
être 0. Seront-ils 0 par défaut ou dois-je faire:
Snapshot s = {0,0};
Quelles sont les autres façons de mettre à zéro la structure?
J'ai ceci struct
:
struct Snapshot
{
double x;
int y;
};
Je veux x
et y
être 0. Seront-ils 0 par défaut ou dois-je faire:
Snapshot s = {0,0};
Quelles sont les autres façons de mettre à zéro la structure?
Réponses:
Ils ne sont pas nuls si vous n'initialisez pas la structure.
Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members
Le second mettra tous les membres à zéro, le premier les laisse à des valeurs non spécifiées. Notez qu'il est récursif:
struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members
Le second fera p.s.{x,y}
zéro. Vous ne pouvez pas utiliser ces listes d'initialisation agrégées si vous avez des constructeurs dans votre structure. Si tel est le cas, vous devrez ajouter une bonne initialisation à ces constructeurs
struct Snapshot {
int x;
double y;
Snapshot():x(0),y(0) { }
// other ctors / functions...
};
Initialise à la fois x et y à 0. Notez que vous pouvez utiliser x(), y()
pour les initialiser sans tenir compte de leur type: c'est alors l'initialisation de la valeur, et donne généralement une valeur initiale correcte (0 pour int, 0,0 pour double, appelant le constructeur par défaut pour défini par l'utilisateur types qui ont des constructeurs déclarés par l'utilisateur, ...). Ceci est important surtout si votre structure est un modèle.
Snapshot s = {};
pour les non-membres du POD (pour les mettre à zéro)?
Non, ils ne sont pas 0 par défaut. Le moyen le plus simple de s'assurer que toutes les valeurs ou par défaut à 0 est de définir un constructeur
Snapshot() : x(0), y(0) {
}
Cela garantit que toutes les utilisations de Snapshot auront des valeurs initialisées.
En général, non. Cependant, une structure déclarée comme portée de fichier ou statique dans une fonction / sera / sera initialisée à 0 (comme toutes les autres variables de ces étendues):
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
}
Avec POD, vous pouvez également écrire
Snapshot s = {};
Vous ne devez pas utiliser memset en C ++, memset a l'inconvénient que s'il y a un non-POD dans la structure, il le détruira.
ou comme ça:
struct init
{
template <typename T>
operator T * ()
{
return new T();
}
};
Snapshot* s = init();
SomeType foo();
c'est le cas typique, bien que cela puisse arriver avec d'autres - en définitions de fonctions (dans ce cas, une fonction foo
qui revient SomeType
). Désolé pour la nécro, mais si quelqu'un d'autre tombe dessus, j'ai pensé que je répondrais.
En C ++, utilisez des constructeurs sans argument. En C, vous ne pouvez pas avoir de constructeurs, utilisez donc soit memset
ou - la solution intéressante - les initialiseurs désignés:
struct Snapshot s = { .x = 0.0, .y = 0.0 };
Je crois que la bonne réponse est que leurs valeurs ne sont pas définies. Souvent, ils sont initialisés à 0 lors de l'exécution des versions de débogage du code. Ce n'est généralement pas le cas lors de l'exécution des versions.
0
dans ces emplacements en mémoire. Ce n'est pas la même chose que l'initialisation!
Comme il s'agit d'un POD (essentiellement une structure C), il n'y a pas de mal à l'initialiser de la manière C:
Snapshot s;
memset(&s, 0, sizeof (s));
ou similaire
Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));
Je n'irais pas jusqu'à utiliser calloc()
dans un programme C ++.
Déplacez les membres du pod vers une classe de base pour raccourcir votre liste d'initialisation:
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());
}