Pergunta

Eu li um livro S. Lippman "Inside C ++ Object Model", existe esse código

class Foo { public: int val; Foo *pnext; };
void foo_bar()
{
// Oops: program needs bar's members zeroed out
Foo bar;
Foo* baz = new Foo(); // this line i added myself
if ( bar.val || bar.pnext )
// ... do something
// ...
}

E diz que "um construtor padrão não é sintetizado para este fragmento de código.

Os objetos globais têm a garantia de ter sua memória associada "zero" na inicialização do programa. Os objetos locais alocados na pilha de programas e nos objetos Heap alocados na loja não possuem sua memória associada zerada; Em vez disso, a memória mantém o padrão de bit arbitrário de seu uso anterior. "

Neste código, o objeto BAZ foi criado na pilha e, de acordo com o que foi dito acima, esse objeto não é global e não será chamado de construtor padrão. Eu entendo corretamente?

Foi útil?

Solução

Os parênteses entram new Foo() especificamos Valor inicialização; Isso basicamente significa que cada membro é zero inicializado. Se você disse new Foo, então os membros seriam deixados não iniciados, como são para sua variável automática.

Infelizmente, para valorizar a variável automática, você não pode escrever Foo bar(), já que isso declara uma função. Você precisará

Foo bar{};        // C++11
Foo bar = Foo();  // Historical C++

Outras dicas

Quando você faz isso:

Foo* baz = new Foo();

você está alocando dinamicamente um Foo instância e Inicialização por valor isto. Para os pods, isso significa que os membros ficam zero iniciais. Se você tivesse dito isso (assumindo o contexto não global):

Foo* baz = new Foo;

então o Foo A instância seria inicializada padrão, o que significa que nenhuma inicialização de seus membros é realizada, pois são vagens.

Isso também se aplica a instâncias automáticas de armazenamento:

Foo f0; // default initializaiton: members not zeroed out.
Foo f1 = Foo(); // value initialization: members zeroed out.
Foo f2{}; // C++11 value initialization: members zeroed out.
Foo f3(); // Ooops! Function declaration. Something completely different.

Se uma classe não tiver um construtor padrão (e nenhum outro construtor), o compilador criará um para você. Tem que, ou você não seria capaz de criar instâncias da classe. No entanto, o construtor padrão gerado não fará nada.

O que adicionar o conjunto vazio de parênteses em new Foo() é, é valorizar inicializar o objeto alocado, o que significa que os membros são inicializados com seus valores "padrão", que é zero para valores inteiros e de ponto flutuante, e nullptr para ponteiros.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top