2012-01-18 17 views
8

Últimamente, he estado leyendo mucho sobre constructores desde C++ FAQ bien recibido. Una de las entradas menciona que siempre es mejor utilizar listas de inicialización, en lugar de inicializar miembros de la clase dentro del bloque de código del propio constructor.Inicializando miembros de clase no punteros

Esto se debe a que el compilador tiende a crear varias copias de los miembros de la clase, en lugar de simplemente una copia.

Ejemplo

Buena

Foo::Foo(void) 
    : mBar(new Bar) //pointer to some memory address 
{ 
} 

Malo

Foo::Foo(void) 
{ 
    mBar = new Bar; 
} 

Una cosa que también establece (y, mientras esto se relaciona con los constructores, que se refiere también a pura inicialización de objetos en géneros l incluso de funciones no miembro) es que cuando la inicialización de un objeto a través de métodos tales como los siguientes:

void f(void) 
{ 
    Foo foo(Bar()); //Bad. 

    foo.x(); //error 
} 

Usted, y cito: "[declare] a non-member function that returns a Foo object".

(para más información, haga clic en el siguiente enlace)

La pregunta

Debido a esto, es prudente tener lo siguiente:

O incluso esto:

Geometry::Geometry(void) 
    : mFaces(QVector<GLushort>), 
     mFinalized(false), 
     mNormals(QVector<QVector3D>), 
     mVerticies(QVector<QVector3D>) 

Por la forma en que t Si se asignan estos (es decir, el hecho de que estos no son punteros), me pregunto si estos objetos incluso NECESITAN la inicialización al principio. Si lo hacen, ¿es este el método correcto para solucionarlo? O, ¿hay un mejor método de inicialización?

cómo esto se relaciona con la cuestión

Esto se relaciona con la cuestión general, debido a la forma en que la metodología detrás de C++ de inicialización del constructor se refiere tanto a los objetos de inicialización utilizando funciones constructoras, junto con el hecho de que yo soy un ignorante a si los objetos asignados en la pila - o, por lo que creo de todos modos - (de cualquier manera, objetos sin asignación de puntero) incluso necesitan inicialización en primer lugar.

Respuesta

12

Si una variable miembro es de un tipo de clase con un constructor predeterminado declarado por el usuario, no es necesario mencionarlo explícitamente en la lista de inicialización: su constructor predeterminado se llamará de todos modos, durante la construcción, antes del cuerpo del constructor es ingresado.

Si una variable miembro es un tipo primitivo (como int o bool) o es de un tipo de clase que no tiene ningún constructor-declarada por el usuario, es necesario inicializar explícitamente, de lo contrario no será inicializado (y tendrá un valor desconocido, no se puede leer un objeto no inicializado).

+0

Entonces, ¿eso significa que, de acuerdo con el código anterior, solo estoy creando copias múltiples de los objetos que estoy asignando? – zeboidlund

+3

Cuando usa 'mFaces (QVector < GLushort >())', construye un 'QVector ' temporal, copia la construcción 'mFaces' de ese objeto temporal, luego destruye ese objeto temporal. Entonces, sí, estás creando más objetos de los necesarios. –

Cuestiones relacionadas