c++ - texto - uso de los dos puntos




¿Qué hace un signo de dos puntos después de un nombre de constructor de C++? (6)

Esta pregunta ya tiene una respuesta aquí:

¿Qué hace el operador de dos puntos (":") en este constructor? Es equivalente a MyClass(m_classID = -1, m_userdata = 0); ?

class MyClass {
public:

    MyClass() : m_classID(-1), m_userdata(0) { 
    }

    int m_classID;
    void *m_userdata;
};

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

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

Eso declara un constructor que puede tomar argumentos (para poder crear un MyClass usando MyClass m = MyClass(3, 4) , lo que daría como resultado que m_classID sea ​​3 y m_userdata sea ​​4). Si no pasara argumentos al constructor de MyClass , se crearía un objeto equivalente a la versión con la lista de inicializadores.


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.


Es una lista de inicialización . En su ejemplo, es más o menos así (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;

};

Es una lista de inicialización.

Para cuando ingresas al cuerpo del constructor, todos los campos ya se han construido; si tienen constructores por defecto, esos ya fueron llamados. Ahora, si le 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.

Entonces en el caso de tipos primitivos como int, no hay 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 genera el error C2758: 'MyClass :: member_': debe inicializarse en la lista de inicializadores de la base del constructor / miembro

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_;
};

Esta es una lista de 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 un constructor predeterminado , es decir, uno que se llamará por defecto 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.


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

Lo que está diciendo es que seguirlo será 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.





ctor-initializer