Lista de inicialización de miembros de C ++

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 } 

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?

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 comstackdor no distingue entre los dos tipos de archivos. La distinción importante es entre la statement del contructor y su definición. La lista de inicialización va con la definición, no la statement.
Por lo general, la statement 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 comstackrá). No es inusual proporcionar definiciones de constructor en línea en la statement de clase cuando el constructor está vacío o corto. En ese caso, una lista de inicialización iría dentro de la statement 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; }; 

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 statement.

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(){} };
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.

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.