c++ O construtor padrão inicializa os tipos incorporados?




constructor built-in-types (6)

O construtor padrão (criado pelo compilador) inicializa os tipos internos?


Answer #1

Tecnicamente, eles são inicializados - usando seu construtor padrão, que incidentalmente não faz nada além de alocar a memória para eles.

Se o que você queria saber é se eles estão definidos como algo sã como 0 para int s, então a resposta é "não".


Answer #2

Como os palestrantes anteriores afirmaram - não, eles não foram inicializados.

Isso é realmente uma fonte de erros realmente estranhos, já que os sistemas operacionais modernos tendem a preencher zeros com regiões de memória recém-alocadas. Se você espera isso, pode funcionar na primeira vez. No entanto, à medida que seu aplicativo continua sendo executado, delete -ing e new -ing objects, você acabará, mais cedo ou mais tarde, em uma situação em que você espera zeros, mas um resto não-zero de um objeto anterior fica.

Então, por que isso, então, não são todos os new dados recém-alocados? Sim, mas nem sempre do sistema operacional. O sistema operacional tende a trabalhar com grandes blocos de memória (por exemplo, 4 MB por vez), de modo que todas as pequenas alocações e desalocações de uma palavra-aqui-três-bytes-lá são tratadas no espaço ocioso e, portanto, não zeradas.

PS. Eu escrevi "tendem a", ou seja, você não pode confiar no sucesso da primeira vez ...


Answer #3

Definitivamente definido (pelo compilador) construtor padrão de uma classe não inicializa membros de tipos internos.

No entanto, você deve ter em mente que, em alguns casos, a inicialização de uma instância da classe pode ser executada por outros meios. Não por construtor padrão, nem por construtor.

Por exemplo, há uma crença incorreta difundida de que, para a classe C a sintaxe C() sempre chama o construtor padrão. Na realidade, a sintaxe C() executa a chamada inicialização de valor da instância de classe. Ele só chamará o construtor padrão se ele for declarado pelo usuário . (Isso é em C ++ 03. Em C ++ 98 - somente se a classe for não-POD). Se a classe não tiver um construtor declarado pelo usuário, o C() não chamará o construtor padrão fornecido pelo compilador, mas executará um tipo especial de inicialização que não envolverá o construtor de C Em vez disso, ele irá inicializar diretamente todos os membros da classe. Para tipos incorporados, resulta em inicialização zero.

Por exemplo, se sua classe não tiver um construtor declarado pelo usuário

class C { 
  int x;
};

então o compilador implicitamente fornecerá um. O construtor fornecido pelo compilador não fará nada, o que significa que não inicializará C::x

C c; // Compiler-provided default constructor is used
// Here `c.x` contains garbage

No entanto, as seguintes inicializações inicializarão zero x porque usam o inicializador explicit ()

C c = C(); // Does not use default constructor for `C()` part
           // Uses value-initialization feature instead
assert(c.x == 0);

C *pc = new C(); // Does not use default constructor for `C()` part
                 // Uses value-initialization feature instead
assert(pc->x == 0);

O comportamento do inicializador () é diferente em alguns aspectos entre C ++ 98 e C ++ 03, mas não neste caso. Para a classe C acima, ela será a mesma: () inicializador executa a inicialização zero de C::x .

Outro exemplo de inicialização que é executado sem envolver o construtor é, obviamente, a inicialização agregada

C c = {}; // Does not use any `C` constructors at all. Same as C c{}; in C++11.
assert(c.x == 0);

C d{}; // C++11 style aggregate initialization.
assert(d.x == 0);

Answer #4

Não tenho certeza do que você quer dizer, mas:

struct A { int x; };

int a; // a is initialized to 0
A b;   // b.x is initialized to 0

int main() {
    int c;         // c is not initialized
    int d = int(); // d is initialized to 0

    A e;           // e.x is not initialized
    A f = A();     // f.x is initialized to 0
}

Em cada caso em que digo "não inicializado" - você pode descobrir que seu compilador fornece um valor consistente, mas o padrão não exige isso.

Muita mão acenando é jogada ao redor, inclusive por mim, sobre como tipos internos "em efeito" possuem um construtor padrão. Na verdade, a inicialização e a inicialização do valor padrão são termos definidos no padrão, que, pessoalmente, tenho de procurar em todas as ocasiões. Apenas classes são definidas no padrão para ter um construtor padrão implícito.


Answer #5

De acordo com o padrão, não a menos que você inicialize explicitamente na lista de inicializadores


Answer #6

Para todos os efeitos práticos - não.

No entanto, para implementações que são tecnicamente compatíveis com o padrão C ++, a resposta é que isso depende se o objeto é POD ou não e como você o inicializa. De acordo com o padrão C ++:

MyNonPodClass instance1;//built in members will not be initialized
MyPodClass instance2;//built in members will be not be initialized
MyPodClass* instance3 = new MyPodClass;//built in members will not be initialized
MyPodClass* instance3 = new MyPodClass() ;//built in members will be zero initialized

No entanto, no mundo real, isso não é bem suportado, então não o use.

As partes relevantes da norma são as seções 8.5.5 e 8.5.7





built-in-types