2010-05-07 31 views
134

duplicados posibles:
Variables After the Colon in a Constructor
C++ constructor syntax question (noob)C++, ¿Qué significa el colon después de un constructor?

Tengo algo de código C++ aquí:

class demo 
{ 
private: 
    unsigned char len, *dat; 

public: 
    demo(unsigned char le = 5, unsigned char default) : len(le) 
    { 
     dat = new char[len];          
     for (int i = 0; i <= le; i++)        
      dat[i] = default; 
    } 

    void ~demo(void) 
    {            
     delete [] *dat;           
    } 
}; 

class newdemo : public demo 
{ 
private: 
    int *dat1; 

public: 
    newdemo(void) : demo(0, 0) 
    { 
    *dat1 = 0;             
    return 0;              
    } 
}; 

Mi pregunta es, ¿cuáles son los : len(le) y : demo(0, 0) llaman?

¿Tiene algo que ver con la herencia?

+5

Duplicado de http://stackoverflow.com/questions/1272680/c-constructor-syntax-question-noob, http://stackoverflow.com/questions/2349978/variables-after-the-colon-in-a -constructor, http://stackoverflow.com/questions/2445330/importance-of-a-singlecolon-in-c, http://stackoverflow.com/questions/1632484/c-initialization-question – outis

+28

** NO ELIMINAR ** preguntas con buenas respuestas! [Jeff dijo eso!] (Http://meta.stackexchange.com/questions/50069/why-are-we-deleting-instead-of-merging/50106#50106) –

+0

@KonradRudolph Se eliminó una de estas preguntas duplicadas, desafortunadamente: http://stackoverflow.com/questions/2445330/importance-of-a-singlecolon-in-c –

Respuesta

187

Como han dicho otros, es una lista de inicialización. Se puede utilizar para dos cosas:

  1. Calling constructores de clase base de
  2. La inicialización de variables miembro antes de que el cuerpo del constructor se ejecuta.

Para el caso n. ° 1, supongo que comprende la herencia (si ese no es el caso, hágamelo saber en los comentarios). Entonces simplemente llama al constructor de su clase base.

Para el caso n. ° 2, se puede formular la pregunta: "¿Por qué no inicializarlo en el cuerpo del constructor?" La importancia de las listas de inicialización es particularmente evidente para los miembros const. Por ejemplo, echar un vistazo a esta situación, donde quiero inicializar m_val basado en el parámetro constructor:

class Demo 
{ 
    Demo(int& val) 
    { 
     m_val = val; 
    } 
private: 
    const int& m_val; 
}; 

por la especificación C++, esto es ilegal. No podemos cambiar el valor de una variable const en el constructor, porque está marcado como const. Por lo tanto, puede usar la lista de inicialización:

class Demo 
{ 
    Demo(int& val) : m_val(val) 
    { 
    } 
private: 
    const int& m_val; 
}; 

Ese es el único momento en que puede cambiar una variable de miembro const. Y como observó Michael en la sección de comentarios, también es la única forma de inicializar una referencia que es un miembro de la clase.

Fuera de usarlo para inicializar las variables de miembro const, parece que se ha aceptado generalmente como "la forma" de inicializar variables, por lo que es claro para otros programadores que leen su código.

+13

Para ser claros, además de inicializar los miembros 'const', es la única forma de inicializar los miembros de referencia, ya sea' const' o no (ya que una asignación a una referencia es una asignación a lo que se refiere la referencia). –

+0

podemos hacer algo como esto 'demo(): m_val (NULL)' que estoy haciendo esto, pero su produce errores, alguna idea de lo que estoy haciendo mal – 2am

+1

1 atento :) –

6

Se llama lista de inicialización. Inicializa los miembros antes de que se ejecute el cuerpo del constructor.

22

Esto se llama una lista de inicialización. Es para pasar argumentos al constructor de una clase padre. Aquí hay un buen enlace que lo explica: Initialization Lists in C++

6

Se llama lista de inicialización. Una lista de inicializadores es cómo pasa argumentos a los constructores de sus variables miembro y para pasar argumentos al constructor de la clase padre.

Si usa = para asignar en el cuerpo del constructor, primero se llama al constructor predeterminado, luego se llama al operador de asignación. Esto es un poco derrochador, y a veces no hay un operador de asignación equivalente.

1

Está llamando al constructor de su clase base, demo.

1

Significa que len no se establece utilizando el constructor predeterminado. mientras se está construyendo la clase demo. Por ejemplo:

class Demo{ 
    int foo; 
public: 
    Demo(){ foo = 1;} 
}; 

Primero pondría un valor en foo antes de establecerlo en 1. Es un poco más rápido y más eficiente.