Internamente e sobre o código gerado, existe realmente uma diferença entre:
MyClass::MyClass(): _capacity(15), _data(NULL), _len(0)
{
}
e
MyClass::MyClass()
{
_capacity=15;
_data=NULL;
_len=0
}
obrigado...
Internamente e sobre o código gerado, existe realmente uma diferença entre:
MyClass::MyClass(): _capacity(15), _data(NULL), _len(0)
{
}
e
MyClass::MyClass()
{
_capacity=15;
_data=NULL;
_len=0
}
obrigado...
Supondo que esses valores sejam tipos primitivos, então não, não há diferença. As listas de inicialização só fazem diferença quando você tem objetos como membros, pois em vez de usar a inicialização padrão seguida pela atribuição, a lista de inicialização permite inicializar o objeto com seu valor final. Na verdade, isso pode ser visivelmente mais rápido.
Você precisa usar a lista de inicialização para inicializar membros constantes, referências e classe base
Quando você precisa inicializar um membro constante, referências e passar parâmetros para os construtores da classe base, conforme mencionado nos comentários, você precisa usar a lista de inicialização.
Exemplo de classe / estrutura (não exaustiva) contém referência:
E um exemplo de inicialização de classe base que requer um parâmetro (por exemplo, nenhum construtor padrão):
fonte
_capacity
,_data
e_len
tiver tipos de classe sem construtores padrão acessíveis?const
membro no corpo do construtor, você deve usar a lista de inicialização - nãoconst
membros podem ser inicializados na lista de inicialização ou no corpo do construtor.Sim. No primeiro caso, você pode declarar
_capacity
,_data
e_len
como constantes:Isso seria importante se você quiser garantir a
const
-ness dessas variáveis de instância ao calcular seus valores em tempo de execução, por exemplo:const
as instâncias devem ser inicializadas na lista de inicializadores ou os tipos subjacentes devem fornecer construtores públicos sem parâmetros (o que os tipos primitivos fornecem).fonte
Acho que este link http://www.cplusplus.com/forum/articles/17820/ dá uma explicação excelente - especialmente para aqueles que são novos em C ++.
A razão pela qual as listas de inicializadores são mais eficientes é que, dentro do corpo do construtor, apenas as atribuições ocorrem, não a inicialização. Portanto, se você estiver lidando com um tipo não interno, o construtor padrão para esse objeto já foi chamado antes que o corpo do construtor tenha sido inserido. Dentro do corpo do construtor, você está atribuindo um valor a esse objeto.
Na verdade, esta é uma chamada para o construtor padrão seguida por uma chamada para o operador de atribuição de cópia. A lista de inicializadores permite que você chame o construtor de cópia diretamente, e isso às vezes pode ser significativamente mais rápido (lembre-se de que a lista de inicializadores está antes do corpo do construtor)
fonte
Acrescentarei que, se você tiver membros do tipo de classe sem nenhum construtor padrão disponível, a inicialização é a única maneira de construir sua classe.
fonte
Uma grande diferença é que a atribuição pode inicializar membros de uma classe pai; o inicializador funciona apenas em membros declarados no escopo da classe atual.
fonte
Depende dos tipos envolvidos. A diferença é semelhante entre
e
onde a segunda forma é a lista de inicialização - isto é, faz diferença se o tipo requer argumentos do construtor ou é mais eficiente com argumentos do construtor.
fonte
A verdadeira diferença se resume em como o compilador gcc gera código de máquina e armazena a memória. Explicar:
Certamente, existem outras maneiras de lidar com membros do tipo const. Mas para facilitar sua vida, os escritores do compilador gcc decidem definir algumas regras
fonte
Existe apenas uma maneira de inicializar instâncias de classe base e variáveis de membro não estáticas e é usando a lista de inicializadores.
Se você não especificar uma variável de membro base ou não estática na lista de inicializadores de seu construtor, então esse membro ou base será inicializado por padrão (se o membro / base for um tipo de classe não POD ou array de classe não POD tipos) ou deixados não inicializados.
Uma vez que o corpo do construtor é inserido, todas as bases ou membros terão sido inicializados ou deixados não inicializados (ou seja, eles terão um valor indeterminado). Não há oportunidade no corpo do construtor de influenciar como eles devem ser inicializados.
Você pode atribuir novos valores a membros no corpo do construtor, mas não é possível atribuir a
const
membros ou membros do tipo de classe que se tornaram não atribuíveis e não é possível religar referências.Para tipos integrados e alguns tipos definidos pelo usuário, a atribuição no corpo do construtor pode ter exatamente o mesmo efeito que inicializar com o mesmo valor na lista de inicializadores.
Se você não conseguir nomear um membro ou base em uma lista de inicializadores e essa entidade for uma referência, tiver tipo de classe sem nenhum construtor padrão declarado pelo usuário acessível, for
const
qualificado e ter tipo POD ou for um tipo de classe POD ou array do tipo de classe POD contendo umconst
membro qualificado (direta ou indiretamente), então o programa está mal formado.fonte
Se você escrever uma lista de inicializadores, fará tudo em uma única etapa; se você não escrever uma lista do initilizer, você fará 2 passos: um para declaração e outro para atribuir o valor.
fonte
Há uma diferença entre a lista de inicialização e a instrução de inicialização em um construtor. Vamos considerar o código abaixo:
Quando MyClass é usado, todos os membros serão inicializados antes da primeira instrução em um construtor executado.
Mas, quando MyClass2 é usado, todos os membros não são inicializados quando a primeira instrução em um construtor é executada.
No caso posterior, pode haver problema de regressão quando alguém adiciona algum código em um construtor antes de um determinado membro ser inicializado.
fonte
Aqui está um ponto que não vi outros se referirem a ele:
A classe temporária não possui um ctor padrão. Quando o usamos em outra classe, como segue:
o código não vai compilar, porque o compilador não sabe como inicializar
obj
, porque ele tem apenas um ctor explícito que recebe um valor int, então temos que mudar o ctor da seguinte maneira:Portanto, não se trata apenas de const e referências!
fonte