La lista de inicialización del constructor comienza con dos puntos, seguida de una lista de miembros de datos separados por comas, cada miembro de datos va seguido de un inicializador entre paréntesis. Por ejemplo:

class CExample {
public:
    int a;
    float b;
    //构造函数初始化列表
    CExample(): a(0),b(8.8)
    {}
    //构造函数内部赋值
    CExample()
    {
        a=0;
        b=8.8;
    }
};

En el ejemplo anterior, los resultados de los dos constructores son los mismos. El constructor de arriba (el que usa la lista de inicialización) inicializa explícitamente los miembros de la clase; mientras que el constructor que no usa la lista de inicialización asigna valores a los miembros de la clase, sin realizar una inicialización explícita.

La inicialización y la asignación no tienen mucha diferencia para los miembros de tipos integrados; cualquiera de los constructores anteriores sirve. Para variables miembro de tipos no integrados, para evitar una doble construcción, se recomienda usar la lista de inicialización del constructor de la clase. Pero a veces es obligatorio usar un constructor con lista de inicialización:

  • 1. El tipo del miembro esuna clase sin constructor predeterminado.Si no se proporciona un inicializador explícito, el compilador utiliza implícitamente el constructor predeterminado del tipo del miembro; si la clase no tiene constructor predeterminado, el intento del compilador de usar el constructor predeterminado fallará.
  • 2.miembros constomiembros de tipos de referencia. Porque los objetos const o los tipos de referencia solo pueden inicializarse, no se les puede asignar valores.

¿Qué significa inicializar miembros de datos frente a asignar valores a miembros de datos? ¿Cuál es la diferencia?

Primero clasifique los miembros de datos por tipo y explique según el caso:

  • 1.Tipos de datos integrados, tipos compuestos (punteros, referencias)- Realizarlo en la lista de inicialización de miembros o en el cuerpo del constructor es igual en rendimiento y resultado.
  • 2.Tipos definidos por el usuario (tipos de clase)- El resultado es el mismo, pero hay una gran diferencia en rendimiento. Porque el objeto miembro de datos de tipo clase ya se ha construido antes de entrar al cuerpo de la función; es decir, el trabajo de construir el objeto se realiza en la lista de inicialización de miembros, invocando al constructor. Después de entrar al cuerpo de la función, lo que se hace es asignar al objeto de clase ya construido, y se necesita invocar al operador de asignación por copia para completarlo (si no se proporciona, se usa el comportamiento de asignación miembro a miembro predeterminado del compilador).

Puntos a tener en cuenta:

Orden de inicialización de miembros en la lista de inicialización:

C++ inicializa los miembros de la clase en el orden en que se declaran, no en el orden en que aparecen en la lista de inicialización.

class CMyClass {
    CMyClass(int x, int y);
    int m_x;
    int m_y;
};

CMyClass::CMyClass(int x, int y) : m_y(y), m_x(m_y)
{
};

Podrías pensar que el código anterior primero hará m_y = I, luego m_x = m_y, y al final tendrán el mismo valor. Pero el compilador inicializa primero m_x y luego m_y, porque están declarados en ese orden. El resultado es que m_x tendrá un valor impredecible. Hay dos formas de evitarlo: una es declarar siempre los miembros en el orden en que deseas que se inicialicen; la segunda es que, si decides usar la lista de inicialización, enumeres siempre los miembros en el orden en que se declaran. Esto ayudará a eliminar la confusión.

Dirección original: http://www.cnblogs.com/BlueTzar/articles/1223169.html