O que as seguintes frases significam em C ++:
inicialização zero,
inicialização padrão e
inicialização de valor
O que um desenvolvedor de C ++ deve saber sobre eles?
O que as seguintes frases significam em C ++:
inicialização zero,
inicialização padrão e
inicialização de valor
O que um desenvolvedor de C ++ deve saber sobre eles?
Respostas:
Uma coisa a perceber é que a 'inicialização de valor' é nova no padrão C ++ 2003 - ela não existe no padrão original de 1998 (acho que pode ser a única diferença que é mais do que um esclarecimento). Veja a resposta de Kirill V. Lyadvinsky para as definições diretamente do padrão.
Consulte esta resposta anterior sobre o comportamento de operator new
para obter detalhes sobre os diferentes comportamentos desse tipo de inicialização e quando eles entram em ação (e quando diferem de c ++ 98 para C ++ 03):
O ponto principal da resposta é:
Às vezes, a memória retornada pelo novo operador será inicializada, e outras vezes, dependendo do tipo que você está iniciando, seja um POD ou se é uma classe que contém membros do POD e está usando um construtor padrão gerado pelo compilador .
- No C ++ 1998, existem 2 tipos de inicialização: zero e padrão
- No C ++ 2003, um terceiro tipo de inicialização foi adicionado à inicialização do valor.
Para dizer o mínimo, é bastante complexo e quando os diferentes métodos são sutis.
Certamente, é importante estar ciente de que o MSVC segue as regras do C ++ 98, mesmo no VS 2008 (VC 9 ou cl.exe versão 15.x).
O seguinte snippet mostra que o MSVC e o Digital Mars seguem as regras do C ++ 98, enquanto o GCC 3.4.5 e o Comeau seguem as regras do C ++ 03:
#include <cstdio>
#include <cstring>
#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)];
std::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
std::printf( "m is %d\n", pB->m);
return 0;
}
int
, mas m()
na terceira linha o valor inicializa m. Importante se você mudar int m;
para B m;
. :)
A
e C
não são usados neste exemplo (eles são herdados da outra resposta vinculada). Embora o C ++ 98 e o C ++ 03 usem terminologia diferente ao descrever como A
e C
são construídos, o resultado é o mesmo nos dois padrões. Apenas struct B
resulta em comportamento diferente.
struct C { C() : m() {}; ~C(); B m; };
, você terá m.m
0. Mas, se inicializar m
como padrão, como você diz C ++ 03, m.m
não será inicializado como em C ++ 98.
Padrão C ++ 03 8.5 / 5:
Para inicializar com zero um objeto do tipo T significa:
- se T é um tipo escalar (3.9), o objeto é definido com o valor de 0 (zero) convertido em T;
- se T é um tipo de classe sem união, cada membro de dados não estático e cada subobjeto da classe base são inicializados com zero;
- se T é um tipo de união, o primeiro membro de dados nomeado do objeto é inicializado com zero;
- se T é um tipo de matriz, cada elemento é inicializado com zero;
- se T é um tipo de referência, nenhuma inicialização é executada.Para inicializar por padrão um objeto do tipo T significa:
- se T é um tipo de classe não-POD (cláusula 9), o construtor padrão para T é chamado (e a inicialização é incorreta se T não tiver construtor padrão acessível);
- se T é um tipo de matriz, cada elemento é inicializado por padrão;
- caso contrário, o objeto será inicializado com zero.Para inicializar com valor um objeto do tipo T significa:
- se T é um tipo de classe (cláusula 9) com um construtor declarado pelo usuário (12.1), o construtor padrão para T é chamado (e a inicialização é mal formada se T não possui construtor padrão acessível);
- se T é um tipo de classe sem união, sem um construtor declarado pelo usuário, todos os membros de dados não estáticos e componentes da classe base de T são inicializados por valor;
- se T é um tipo de matriz, então cada elemento é inicializado por valor;
- caso contrário, o objeto será inicializado com zeroUm programa que solicita a inicialização padrão ou a inicialização de valor de uma entidade do tipo de referência está incorreto. Se T for um tipo qualificado de cv, a versão não qualificada de cv de T será usada para essas definições de inicialização zero, inicialização padrão e inicialização de valor.