Eu sempre vi que as pessoas criam objetos em C ++ usando
Thing myThing("asdf");
Em vez disso:
Thing myThing = Thing("asdf");
Isso parece funcionar (usando o gcc), pelo menos enquanto não houver modelos envolvidos. Minha pergunta agora, a primeira linha está correta e, em caso afirmativo, devo usá-la?
Respostas:
As duas linhas estão de fato corretas, mas fazem coisas sutilmente diferentes.
A primeira linha cria um novo objeto na pilha chamando um construtor do formato
Thing(const char*)
.O segundo é um pouco mais complexo. Essencialmente, faz o seguinte
Thing
usando o construtorThing(const char*)
Thing
usando o construtorThing(const Thing&)
~Thing()
o objeto criado na etapa # 1fonte
Thing myThing = Thing(...)
não usa o operador de atribuição, é ainda cópia construído apenas como dizerThing myThing(Thing(...))
, e não envolve um construído-defaultThing
(edit: pós foi posteriormente corrigida)Suponho que com a segunda linha você realmente queira dizer:
que seria a maneira padrão de criar novos objetos dinâmicos (necessários para ligação dinâmica e polimorfismo) e armazenar seu endereço em um ponteiro. Seu código faz o que JaredPar descreveu, ou seja, criar dois objetos (um passou a
const char*
, o outro passou aconst Thing&
) e, em seguida, chamar o destruidor (~Thing()
) no primeiro objeto (oconst char*
aquele).Por outro lado, isso:
cria um objeto estático que é destruído automaticamente ao sair do escopo atual.
fonte
O compilador pode otimizar o segundo formulário para o primeiro, mas não precisa.
Saída do gcc 4.4:
fonte
Simplesmente, ambas as linhas criam o objeto na pilha, em vez de no heap como 'new'. A segunda linha, na verdade, envolve uma segunda chamada para um construtor de cópias, portanto deve ser evitada (também precisa ser corrigida conforme indicado nos comentários). Você deve usar a pilha para objetos pequenos o máximo possível, pois é mais rápida; no entanto, se seus objetos sobreviverem por mais tempo que o quadro da pilha, é claramente a escolha errada.
fonte
Idealmente, um compilador otimizaria o segundo, mas não é necessário. O primeiro é o melhor caminho. No entanto, é bastante crítico entender a distinção entre pilha e pilha no C ++, pois você deve gerenciar sua própria memória de pilha.
fonte
Eu brinquei um pouco com isso e a sintaxe parece bastante estranha quando um construtor não aceita argumentos. Deixe-me dar um exemplo:
então apenas escrever Thing myThing sem colchetes realmente chama o construtor, enquanto Thing myThing () faz com que o compilador deseje criar um ponteiro de função ou algo assim ?? !!
fonte
Em anexo a JaredPar resposta
1-Ctor usual, 2-Função-como-Ctor com objeto temporário.
Compile esta fonte em algum lugar aqui http://melpon.org/wandbox/ com diferentes compiladores
E você verá o resultado.
ISO / IEC 14882 2003-10-15
Sua primeira e segunda construção são chamadas de inicialização direta
Onde ler sobre o RVO:
Desative-o com o sinalizador do compilador do comentário para visualizar esse comportamento de cópia)
fonte