2009-03-17 21 views

Respuesta

49

El orden es:

  1. Base constructor
  2. constructor Derivado
  3. destructor Derivado
  4. Base destructor

Ejemplo:

class B 
{ 
public: 
    B() 
    { 
    cout<<"Construct B"<<endl; 
    } 

    virtual ~B() 
    { 
    cout<<"Destruct B"<<endl; 
    } 
}; 

class D : public B 
{ 
public: 
    D() 
    { 
    cout<<"Construct D"<<endl; 
    } 

    virtual ~D() 
    { 
    cout<<"Destruct D"<<endl; 
    } 
}; 



int main(int argc, char **argv) 
{ 
    D d; 
    return 0; 
} 

salida de ejemplo:

Construct B

Construct D

Destruct D

Destruct B

múltiples niveles de herencia funciona como una pila:

Si se tiene en cuenta que empuja un elemento en la pila como la construcción, y quitarse la destrucción, a continuación, se puede ver en múltiples niveles de herencia como una pila.

Esto funciona para cualquier cantidad de niveles.

Ejemplo D2 deriva de D se deriva de B.

Empuje B en la pila, empuje D en la pila, empuje D2 en la pila. Entonces, el orden de construcción es B, D, D2. Luego, para descubrir la orden de destrucción, comience a aparecer. D2, D, B

ejemplos más complicados:

Para ejemplos más complicados, consulte el enlace proporcionado por @JaredPar

+1

Tal vez el OP quiere saber sobre la clase D: public A, B, C ... –

+1

La herencia múltiple agrega cierta complejidad: http://www.gotw.ca/gotw/080.htm –

9

Además, tenga en cuenta que mientras que elementos de la matriz se construyen primero -> última, que se destruyen en el orden inverso: el pasado -> primero.

+1

+1 Eso es cierto para casi todo. El orden de destrucción es siempre lo opuesto a la construcción. Las variables estáticas no tienen un orden de construcción garantizado, pero la destrucción ocurrirá en orden inverso. –

+0

¿Es eso (esperado) el comportamiento de contenedor templado y/o el comportamiento incorporado 'new []'/'delete []'? – franji1

2

debo añadir a las respuestas anteriores porque todo el mundo parece ignorar que

Cuando se tiene un deriva instancia de clase siendo creado, es cierto que el código dentro el constructor de la base de se llamará antes el código dentro el constructor de la deriva, pero tenga en cuenta que la deriva es todavía técnicamente "creado"antes la base de.

Y cuando se tiene la destructor de la clase derivada de ser llamado, es cierto que el código dentro el destructor derivada se llama antes el código dentro el destructor de base, sino también mantener en cuenta que la base de es destruidosantes de la deriva.

Cuando digo creada/destruidos De hecho, me refiero a asignado/desasignado.

Si observa el diseño de memoria de estas instancias, verá que la instancia derivada compone la instancia base. Por ejemplo:

memoria de derivados: 0x00001110 a 0x00001120

memoria de la base: 0x00001114 a 0x00001118

Por lo tanto, la clase derivada debe asignarse ANTES la base en la construcción. Y la clase derivada debe desasignarse DESPUÉS la base en la destrucción.

Si tiene el siguiente código:

class Base 
{ 
public: 
    Base() 
    { 
     std::cout << "\n Base created"; 
    } 
    virtual ~Base() 
    { 
     std::cout << "\n Base destroyed"; 
    } 
} 

class Derived : public Base 
{ 
public: 
    Derived() 
    // Derived is allocated here 
    // then Base constructor is called to allocate base and prepare it 
    { 
     std::cout << "\n Derived created"; 
    } 
    ~Derived() 
    { 
     std::cout << "\n Derived destroyed"; 
    } 
    // Base destructor is called here 
    // then Derived is deallocated 
} 

Así que si Derived d; creado y tuvo que salir de su ámbito, por lo que recibirá la salida de @ respuesta de Brian.Sin embargo, el comportamiento de los objetos en la memoria no es realmente el en mismo orden, es de la misma familia:

construcción:

  1. derivados asignados

  2. Base asignados constructor

  3. base llamada

  4. constructor derivado llamado

Destrucción:

  1. destructor Derivado llamado

  2. destructor base llamada

  3. Base desasignado

  4. Derivado desasignar

Cuestiones relacionadas