Inicialización vs Asignación
Posted by gfaraj on May 2, 2007
Hay una diferencia entre inicialización y asignación. Una inicialización se hace al momento de crear un objeto, una asignación se hace después de la creación. Por ejemplo.
int x = 10; // inicializacion int x(10); // inicializacion int y; y = 10; // asignacion
C++ no inicializa los tipos primitivos automaticamente. La diferencia entre inicialicacón y asignación es mas importante cuando se trata de clases, ya que en C++ las clases si se inicializan automaticamente usando el constructor default.
class Arreglo { int* _data; int _cantidad; public: explicit Arreglo(int cantidad = 10) : _cantidad(cantidad), _data(new int[cantidad]) { } Arreglo(Arreglo const& copia) : _cantidad(copia._cantidad), _data(new int[copia_cantidad]) { std:copy(copia._data, copia._data + copia._cantidad, _data); } ~Arreglo() { delete[] _data; } Arreglo& operator=(Arreglo const& copia) { delete[] _data; _cantidad = copia._cantidad; _data = new int[_cantidad]; std:copy(copia._data, copia._data + _cantidad, _data); return *this; } }
Esta es una clase sencilla (e incompleta) que abstrae el manejo de un arreglo dinamico. Tiene implementado el constructor de copia y el operador de asignacion para que sea seguro y haga copias profundas del objeto. Para ilustrar la diferencia entre inicialización y asignación veamos un ejemplo usando la clase de arriba.
int main() { Arreglo arr1(20); Arreglo arr2(arr1); // inicializacion Arreglo arr3; arr3 = arr1; // asignacion }
Ahora, que pasa cuando usamos inicialización? El objeto arr2 crea su arreglo una sola vez y copia el contenido de arr1. Suena bien, no? Ahora que pasa cuando usamos asignación? El objeto arr3 crea su arreglo dos veces! Una vez al crear el objeto, y otra vez cuando se le asigna. Por eso, siempre es recomendable usar inicialización cuando sea posible en vez de asignación. Se deberia usar la lista de inicialización de un constructor en vez de asignar en el cuerpo del constructor cuando sea posible.
// malo class A { public: std::string _str; A(std::string const& str) { _str = str; } }; // bueno class A { public: std::string _str; A(std::string const& str) : _str(str) {} };
Por lo general, usar inicialización va a ser mas eficiente que usar asignación. Hay algunas excepciones asi que lo que hay que hacer es siempre tener sentido comun y usar la que mas conviene.
memmaker650 said
No dejes el blog. Haces artículos muy interesantes y se ve que dominas la inforática y sabes explicarsela a gente que todavía no tiene amplios conocimientos.
pepe said
¿Para qué el uso de ‘explicit’ en el constructor por defecto? Saludos