Eu tenho isso struct
:
struct Snapshot
{
double x;
int y;
};
Eu quero x
e y
seja 0. Eles serão 0 por padrão ou eu tenho que fazer:
Snapshot s = {0,0};
Quais são as outras maneiras de zerar a estrutura?
Eu tenho isso struct
:
struct Snapshot
{
double x;
int y;
};
Eu quero x
e y
seja 0. Eles serão 0 por padrão ou eu tenho que fazer:
Snapshot s = {0,0};
Quais são as outras maneiras de zerar a estrutura?
Respostas:
Eles não serão nulos se você não inicializar a estrutura.
Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members
O segundo fará com que todos os membros sejam zero, o primeiro os deixa com valores não especificados. Observe que é recursivo:
struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members
O segundo fará p.s.{x,y}
zero. Você não pode usar essas listas agregadas de inicializadores se tiver construtores em sua estrutura. Se for esse o caso, você precisará adicionar uma initalização adequada a esses construtores
struct Snapshot {
int x;
double y;
Snapshot():x(0),y(0) { }
// other ctors / functions...
};
Inicializará x e y como 0. Observe que você pode usá x(), y()
-lo para desconsiderar seu tipo: Isso é inicialização de valor e, geralmente, gera um valor inicial adequado (0 para int, 0,0 para double, chamando o construtor padrão para usuário definido tipos que possuem construtores declarados pelo usuário, ...). Isso é importante, especialmente se sua estrutura é um modelo.
Snapshot s = {};
para não membros do POD (para zerá-los)?
Não, eles não são 0 por padrão. A maneira mais simples de garantir que todos os valores ou o padrão seja 0 é definir um construtor
Snapshot() : x(0), y(0) {
}
Isso garante que todos os usos do Snapshot tenham valores inicializados.
Em geral, não. No entanto, uma estrutura declarada como escopo do arquivo ou estática em uma função / será / inicializada em 0 (assim como todas as outras variáveis desses escopos):
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
}
Com POD você também pode escrever
Snapshot s = {};
Você não deve usar o memset em C ++, o memset tem a desvantagem de que, se houver um não-POD na estrutura, ele o destruirá.
ou assim:
struct init
{
template <typename T>
operator T * ()
{
return new T();
}
};
Snapshot* s = init();
SomeType foo();
é o típico, embora possa acontecer com outras pessoas - em definições de função (nesse caso, uma função foo
que retorna SomeType
). Sinto muito pelo necro, mas se alguém mais se deparar com isso, achei que eu responderia.
No C ++, use construtores sem argumento. Em C, você não pode ter construtores; portanto, use um memset
ou - a solução interessante - inicializadores designados:
struct Snapshot s = { .x = 0.0, .y = 0.0 };
Acredito que a resposta correta é que seus valores são indefinidos. Geralmente, eles são inicializados como 0 ao executar versões de depuração do código. Geralmente, esse não é o caso ao executar versões de lançamento.
0
esses lugares na memória. Isso não é o mesmo que inicialização!
Como este é um POD (essencialmente uma estrutura C), há pouco dano em inicializá-lo da maneira C:
Snapshot s;
memset(&s, 0, sizeof (s));
ou similar
Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));
Eu não iria tão longe a ponto de usar calloc()
em um programa C ++.
Mova os membros do pod para uma classe base para reduzir sua lista de inicializadores:
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());
}