2009-08-13 16 views

Respuesta

79

Esta es una lista inicialización, y es parte de la implementación del constructor.

La firma del constructor es:

MyClass(); 

Esto significa que el constructor puede ser llamado sin parámetros. Esto lo convierte en constructor predeterminado, es decir, uno que se llamará de manera predeterminada cuando escriba MyClass someObject;.

La parte : m_classID(-1), m_userdata(0) se llama lista de inicialización. Es una forma de inicializar algunos campos de su objeto (todos ellos, si lo desea) con valores de su elección, en lugar de dejarlos como indefinidos.

Después de ejecutar la lista de inicialización, se ejecuta el cuerpo del constructor (que está vacío en su ejemplo). Dentro de él podría hacer más asignaciones, pero una vez que lo haya ingresado, todos los campos ya se han inicializado, ya sea al azar, valores no especificados, o a los que elija en su lista de inicialización. Esto significa que las asignaciones que haga en el cuerpo constructor no serán inicializaciones, sino cambios de valores.

2

Indica el comienzo de una lista de inicializadores, que sirve para inicializar las variables miembro de su objeto.

cuanto a: MyClass(m_classID = -1, m_userdata = 0);

que declara un constructor que puede tomar argumentos (por lo que podría crear una MyClass usando MyClass m = MyClass(3, 4), lo que resultaría en m_classID siendo 3, y siendo m_userdata 4). Si no pasara argumentos al constructor MyClass, se crearía un objeto equivalente a la versión con la lista de inicializadores.

0

En este caso: Sí, ist es equivalente porque solo se trata de tipos primitivos.

Si los miembros son clases (estructuras), entonces debería preferir la lista de inicialización. Esto se debe a que, de lo contrario, los objetos se construyen por defecto y luego se asignan.

1

Es un initialization list. En su ejemplo, es más bien algo como esto (algo como esto - no significa que sea equivalente en todos los casos):


class MyClass { 

public: 

    MyClass(){ 
     m_classID = -1; 
     m_userdata = 0; 
    } 

    int m_classID; 
    void *m_userdata; 

};
2

Señala el comienzo de una lista de inicializadores.

Tampoco es equivalente a MyClass (m_classId = -1, m_userData = 0). Esto intenta definir un constructor con 2 parámetros que tienen valores predeterminados. Sin embargo, los valores carecen de tipos y no deberían compilarse en absoluto.

1

Se llama lista de inicialización de miembros. Se utiliza para llamar a los constructores de superclase y dar a sus variables miembro un valor inicial en el momento en que se crean.

En este caso, está inicializando m_classID en -1 y m_userData en NULO.

No es equivalente a la asignación en el cuerpo del constructor, porque este último primero crea las variables miembro y luego las asigna. Con la inicialización, el valor inicial se proporciona en el momento de la creación, por lo que en el caso de objetos complejos, puede ser más eficiente.

+1

Es también a veces una necesidad para utilizar el lista de inicialización de miembros Si tiene una variable miembro que es una referencia, debe configurarla utilizando la lista de inicialización de miembros. – Skurmedel

1

No es precisamente un operador. Es parte de la sintaxis de un constructor.

Lo que está diciendo es que a continuación se mostrará una lista de variables miembro y sus valores iniciales.

Los miembros constantes deben inicializarse de esta manera. Los no constantes se pueden inicializar aquí también, siempre que se pueda hacer con una sola expresión. Si se necesita más código que ese para inicializar un miembro, debe poner el código real entre los {} para hacerlo.

A mucha gente le gusta poner prácticamente todo su código de constructor en la lista de iniciadores. Tengo un compañero de trabajo que regularmente escribe clases con varias pantallas de iniciadores, y luego pone "{}" para el código del constructor.

1

Es el comienzo de una lista de inicializadores que establece variables miembro durante la construcción del objeto. Su ejemplo "MyClass (m_classID = -1, m_userdata = 0);" no es posible, ya que no se ha definido el constructor correcto y que no sería capaz de acceder a las variables miembro en la lista de parámetros de todos modos ... que podría tener algo como:

MyClass(int classId = -1, void* userData = 0) : m_classID(classId), m_userdata(userData) {} 

La lista initialiser se considera mejor que :

MyClass(int classId = -1, void* userData = 0) { 
    m_classID = classId; 
    m_userdata = userData; 
} 

Google para obtener más información.

37

Es una lista de inicialización.

Al momento de ingresar al cuerpo del constructor, todos los campos ya se han construido; si tienen constructores por defecto, esos ya fueron llamados. Ahora, si les asigna un valor en el cuerpo del constructor, está llamando al operador de asignación de copia, lo que puede significar liberar y volver a adquirir recursos (por ejemplo, memoria) si el objeto tiene alguno.

Por lo tanto, en el caso de tipos primitivos como int, no hay ninguna ventaja en comparación con asignarlos en el cuerpo del constructor. En el caso de objetos que tienen un constructor, es una optimización del rendimiento porque evita pasar por dos inicializaciones de objetos en lugar de una.

Una lista de inicialización es necesaria si uno de los campos es una referencia porque una referencia nunca puede ser nula, ni siquiera en el breve tiempo entre la construcción del objeto y el cuerpo del constructor. A continuación se plantea C2758 de error: 'MyClass :: member_': Se debe inicializar en la base del constructor/lista de inicialización miembro de

class MyClass { 
public : 
    MyClass(std::string& arg) { 
     member_ = arg; 
    } 
    std::string& member_; 
}; 

La única forma correcta es:

class MyClass { 
public : 
    MyClass(std::string& arg) 
     : member_(arg) 
    { 
    } 
    std::string& member_; 
}; 
+2

A menudo se cree erróneamente que si tiene un miembro de referencia, * tiene * que definir un constructor con una lista de inicializadores de constructor.Pero eso no es del todo cierto. Un simple 'MyClass m = {arg};' también funcionará bien. –

+0

litb: pero luego se le requiere más o menos usar m = {arg}; ¿No eres tú? En mi opinión, ser capaz de hacer MyClass m (ref) es bastante deseado. – Skurmedel

+0

@Skurmedel, estoy de acuerdo. Pero eso no significa que sea la única forma de hacerlo, por supuesto. –

Cuestiones relacionadas