programación - Lista de inicialización de miembros de C++
programación en c++ para ingenieros (6)
Explique cómo usar las listas de inicialización de miembros. Tengo una clase declarada en un archivo .h
y un archivo .cpp
como este:
class Example
{
private:
int m_top;
const int m_size;
...
public:
Example ( int size, int grow_by = 1 ) : m_size(5), m_top(-1);
...
~Example();
};
Estoy inicializando m_size
en la creación de objetos debido a const
. ¿Cómo debería escribir el constructor? ¿Debo repetir : m_size(5), m_top(-1)
o puedo omitir este paso?
Example::Example( int size, int grow_by)
{
... some code here
}
o
Example::Example( int size, int grow_by) : m_size(5), m_top(-1)
{
... some code here
}
Al agregar respuestas a los demás, lo más importante que se debe recordar acerca de la lista de inicialización es que the order of initialization is decided in the order in which the data members are declared, not the the order in which you have initialized the data members using initialization list
Considera el ejemplo (el tuyo):
class Example
{
private:
int m_top;
const int m_size;
...
public:
Example ( int size, int grow_by = 1 ) : m_size(5), m_top(-1){}
/* Though size is initialized with a value first
But it is m_top variable that is assigned value -1
before m_size is assigned value 5 */
...
~Example(){}
};
Si uno no está enterado de lo anterior, puede causar implicaciones muy serias.
En C ++ 11 puede usar la inicialización de miembros de datos no estáticos . Esto es especialmente útil si tiene varios constructores que necesitan un valor común para una variable miembro.
class Example
{
private:
int m_top = -1;
const int m_size = 5;
...
public:
Example ( int size, int grow_by = 1 );
...
~Example();
};
...
Example::Example( int size, int grow_by )
{
... some code here
}
Puede anular el valor en un constructor si es necesario.
Esta es la lista de inicialización:
Example::Example( int size, int grow_by) : m_size(5), m_top(-1)
{
... some code here
}
y debe hacerse solo en el archivo cpp.
¿No obtienes un error cuando lo haces como lo hiciste en el encabezado de tu ejemplo?
La lista de inicializadores de miembros es una parte de la definición en el archivo fuente.
Escribe esto en un archivo cpp:
Example ( int size, int grow_by) : m_size(5), m_top(-1)
{
}
El archivo de encabezado solo debe tener:
Example ( int size, int grow_by = 1 );
El archivo de encabezado solo declara el constructor, la lista de inicializador de miembros no es parte de la declaración.
No puede tener una lista de inicialización tanto en el encabezado como en cpp. La lista debe estar en el archivo que define tu constructor. También debe incluir un cuerpo para el constructor, incluso si está vacío.
En una nota lateral, solo debe especificar los argumentos predeterminados en el prototipo de función que no está en la definición.
Solo para aclarar algo que surgió en algunas de las otras respuestas ...
No es necesario que la lista de inicialización esté en el archivo de origen (.cpp) o en el encabezado (.h). De hecho, el compilador no distingue entre los dos tipos de archivos. La distinción importante es entre la declaration del contructor y su definición. La lista de inicialización va con la definición, no la declaración.
Por lo general, la declaración está en un archivo de encabezado y la definición está en un archivo fuente, sin embargo, este no es un requisito del lenguaje (es decir, se compilará). No es inusual proporcionar definiciones de constructor en línea en la declaración de clase cuando el constructor está vacío o corto. En ese caso, una lista de inicialización iría dentro de la declaración de clase, que probablemente estaría en un archivo de encabezado.
MyClass.h
class MyClass
{
public:
MyClass(int value) : m_value(value)
{}
private:
int m_value;
};