O que as seguintes frases significam em C ++: zero, inadimplência e de valor de inicialização?
-
06-07-2019 - |
Pergunta
O que as seguintes frases significam em C ++:
-
zero inicialização,
-
default-inicialização e
-
valor de inicialização
O que deve um desenvolvedor C ++ sabe sobre eles?
Solução
Uma coisa a entender é que 'valor-inicialização' é novo com o C ++ 2003 Standard - não existe no padrão 1998 original (eu acho que pode ser a única diferença que é mais do que um esclarecimento). Consulte Kirill do V. Lyadvinsky resposta para as definições em linha reta do padrão.
Veja esta resposta anterior sobre o comportamento de operator new
para obter detalhes sobre o comportamento diferente deste tipo de inicialização e quando chutar (e quando eles diferem de c ++ 98 para C ++ 03):
O principal ponto da resposta é:
Às vezes a memória devolvida pelo novo operador será inicializado, e às vezes não, dependendo se o tipo que você está Newing up é um POD, ou se é uma classe que contém membros POD e está usando uma compiler- construtor padrão gerado.
- Em C ++ 1998, existem 2 tipos de inicialização: zero e padrão
- Em C ++ 2003, um 3º tipo de inicialização, inicialização valor foi adicionado.
Para dizer que eles menos, é bastante complexo e quando os diferentes métodos chutar são sutis.
Uma coisa a ser certamente ciente de que MSVC segue as C ++ 98 regras, mesmo em VS 2008 (VC 9 ou versão cl.exe 15.x).
A seguir mostra trecho que MSVC e Marte Digital seguem C ++ 98 regras, enquanto GCC 3.4.5 e Comeau seguem o C ++ 03 regras:
#include <stdio.h>
#include <string.h>
#include <new>
struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m
int main()
{
char buf[sizeof(B)];
memset( buf, 0x5a, sizeof( buf));
// use placement new on the memset'ed buffer to make sure
// if we see a zero result it's due to an explicit
// value initialization
B* pB = new(buf) B(); //C++98 rules - pB->m is uninitialized
//C++03 rules - pB->m is set to 0
printf( "m is %d\n", pB->m);
return 0;
}
Outras dicas
C ++ 03 Padrão 8.5 / 5:
Para zero initialize um objeto de meios tipo T:
- no caso de T é um tipo escalar (3,9), o objecto é definido como o valor de 0 (zero) convertido em T;
- Se T é um tipo de classe não-união, cada membro de dados não estático e cada sub-objeto da classe base é zero-inicializado;
- Se T é um tipo de união, primeiro membro de dados com o nome do objeto é inicializado para zero;
- no caso de T é um tipo de matriz, cada elemento é inicializado para zero;
- Se T é um tipo de referência, nenhuma inicialização é executada.Para default-initialize um objeto de meios tipo T:
- Se T é um POD não-tipo de classe (cláusula 9), o construtor padrão para T é chamado (e a inicialização é mal-formado se T não tem nenhum construtor padrão acessível);
- Se T é um tipo de matriz, cada elemento é inicializado-default;
- de outro modo, o objecto é inicializado para zero.Para valor-initialize um objeto de meios tipo T:
- Se T é um tipo de classe (cláusula 9) com um construtor declarado pelo usuário (12.1), então o construtor padrão para T é chamado (e a inicialização é mal-formado se T não tem nenhum construtor padrão acessível);
- Se T é um tipo de classe não-união sem um construtor declarado pelo usuário, em seguida, todos os componentes membro de dados e base de classe non-static de T é inicializado valor;
- no caso de T é um tipo de matriz, em seguida, cada elemento é inicializado-valor;
- caso contrário, o objeto é inicializado para zeroUm programa que solicita default-inicialização ou valor-inicialização de uma entidade do tipo de referência é mal-formado. Se T é um tipo cv qualificado, a versão cv-incondicional do T é usado para estas definições de zero a inicialização, default-inicialização, eo valor-inicialização.