•
Construtores Explicit
- Não se esqueça que:
Qualquer construtor que é chamado com um argumento pode ser usado pelo
compilador para executar uma conversão implícita, na qual o tipo
recebido pelo construtor é convertido em um objeto da classe na qual o
construtor está definido. A conversão é automatica e o programador
não usar um operador de coerção.
Em alguns lugares, quando o compilador faz isso pode gerar problemas,
ou mesmo o programador não quer que isso aconteça.
Exemplo de Coerção executada pelo compilador:
#include <iostream>
using std::ostream;
using std::cout;
#include <cassert>
class Array {
friend ostream & operator<<( ostream &, const Array & );
public:
Array( int ); // construtor defaut
~Array(); // destruidor
private:
int size;
int *ptr;
};
Array::Array( int vsize = 10 )
{
size = ( vsize > 0 ? vsize : 10 );
cout << "Construtor chamado para " << size << " elementos " << std::endl;
// alocação
ptr = new int[size];
assert( ptr != 0 );
// inicia array
for ( int i=0; i<size; i++ )
{
ptr[i] = 0;
}
}
Array::~Array()
{
delete [] ptr;
}
ostream & operator<<( ostream &output, const Array &varray
)
{
int i=0;
for ( i=0; i<varray.size; i++ )
{
cout << varray.ptr[i] << std::endl;
}
return output;
}
void outputArray( const Array & );
int main()
{
// iniciamos um com 7 elementos
Array vinteger( 7 );
// envia o array para a função
que recebe array
outputArray( vinteger );
// envia o int para
a função
que recebe Array
// como a função receberia um Array e não
um int
// o compilador verifica qual o tipo do construtor de array
// como o construtor de array é int, ele recebe o argumento e executa
o
// construtor
outputArray( 15 );
return 0;
}
void outputArray( const Array &aimprimir )
{
cout << "O array recebido contem "<< aimprimir << std::endl;
}
Para evitar essa execução, devemos usar o operador explicit.
Um construtor que é declarado como explicit não pode ser usado
para conversão implícita.
class Array {
friend ostream & operator<<( ostream &, const Array & );
public:
explicit Array( int ); // construtor defaut
~Array(); // destruidor
private:
int size;
int *ptr;
};
Usando o exemplo anterior, o erro aprensetado pelo compilador será
error C2664: 'outputArray' : cannot convert parameter
1 from 'const int' to 'const class Array &'
Reason: cannot convert from 'const int' to 'const class Array'
No constructor could take the source type, or constructor overload resolution
was ambiguous
|