Inicialização explícita
O C++ oferece suporte a duas formas de inicialização explícita.
Fornecendo uma lista de inicializadores entre parênteses:
String sFileName( "FILE.DAT" );
Os itens na lista entre parênteses são considerados argumentos para o construtor da classe. Esse formulário de inicialização permite a inicialização de um objeto com mais de um valor e também pode ser usado com o operador new. Por exemplo:
Rect *pRect = new Rect( 10, 15, 24, 97 );
Fornecendo um único inicializador usando a sintaxe de inicialização do sinal de igualdade. Por exemplo:
String sFileName = "FILE.DAT";
Embora o exemplo anterior funcione do mesmo modo que o exemplo mostrado para String no primeiro item de lista, a sintaxe não é adaptável para o uso com os objetos alocados no repositório livre.
A única expressão à direita do sinal de igualdade é considerada um argumento para o construtor de cópia da classe; portanto, ela deve ser um tipo que possa ser convertido para o tipo da classe.
Observe que, como o sinal de igualdade (=) no contexto de inicialização é diferente de um operador de atribuição, sobrecarregar operator= não tem nenhum efeito na inicialização.
A sintaxe de inicialização do sinal de igualdade é diferente da sintaxe do estilo da função, mesmo que o código gerado seja idêntico na maioria dos casos. A diferença é que, quando a sintaxe do sinal de igualdade é usada, o compilador deve se comportar como se a seguinte sequência de eventos estivesse ocorrendo:
Criando um objeto temporário do mesmo tipo do objeto que está sendo inicializado.
Copiando o objeto temporário para o objeto.
O construtor deve ser acessível antes que o compilador possa executar essas etapas. Ainda que o compilador possa eliminar a criação temporária e copiar as etapas na maioria dos casos, um construtor de cópia inacessível causa falha da inicialização do sinal de igualdade (em /Za, /Ze (desabilita extensões de linguagem)). Considere o exemplo a seguir:
// spec1_explicit_initialization.cpp
// compile with: /Za
class anInt {
anInt( const anInt © ) {} // private copy constructor
public:
anInt( int ) {} // public constructor
};
int main() {
// Access-control violation.
// Attempt to reference private copy constructor.
anInt myInt = 7; // C2248
anInt myInt2(7); // Correct; no copy constructor called.
}
Quando uma função é chamada, os argumentos do tipo de classe passados por valor e objetos retornados por valor são inicializados conceitualmente usando o formato:
nome do tipo nome = valor
Por exemplo:
String s = "C++";
Portanto, deduz-se que o tipo de argumento deve ser um tipo que possa ser convertido no tipo de classe sendo passado como um argumento. O construtor de cópia da classe, bem como os operadores de conversão definidos pelo usuário ou os construtores que aceitam o tipo do argumento real, devem ser públicos.
Em expressões que usam o operador new, os objetos alocados no repositório livre são inicializados conceitualmente usando o formato:
nome to tipo nome**(** inicializador1, inicializador2, ... inicializadorn )
Por exemplo:
String *ps = new String( "C++" );
Os inicializadores para componentes da classe base e objetos membro de uma classe também são inicializados conceitualmente dessa maneira. (Para obter mais informações, consulte Inicializando bases e membros.)