2009-11-23 12 views
5
class MyClass 
{ 
}; 

void foo 
{ 
    MyClass arr[10]; 
} 

Quiero saber el orden de destrucción de los objetos de la matriz cuando la función retorna.Orden de destrucción para la matriz de objetos

lo leí C++ más eficaz al respecto y se dice que el destructor se invoca en orden inverso al de fin del constructor de la siguiente manera:

for(int i = 9 ; i >= 0 ;i--) 
{ 
    arr[i].MyClass::~MyClass(); 
} 

¿Puede alguien decirme la razón para ello?

Respuesta

2

Es la continuación del orden inverso de la filosofía de invocación de destructor de C++. Cuando se destruyen los objetos asignados por la pila, se realiza en orden inverso para facilitar RAII. Aunque eso no es realmente necesario para los elementos de matriz (todos están construidos con los constructores por defecto y cualquier orden de construcción/destrucción), lo mismo se hace con ellos solo por coherencia.

+1

todos ellos están construidos con los constructores por defecto y cualquier orden de construcción/destrucción sería suficiente. "Dado que un constructor no-arg puede acceder a globales (clase estática por ejemplo), hace una diferencia en la matriz resultante qué orden es ' Reconstruido. Así que no estoy muy seguro de lo que quiere decir con "cualquier pedido" - solo una orden cumple con 12.6 del estándar. El estándar podría haber dicho que el orden fue definido por la implementación, o podría haber dicho que están construidos en orden inverso al número de factores primos distintos en el índice, con vínculos determinados por la suma de dígitos en la base 7 ;-) –

0

Quizás el orden en que los objetos que componen la matriz se colocan en la pila. De todos modos, a excepción de la curiosidad, no puedo pensar en ninguna razón para preocuparse por la orden de destrucción.

+0

Si arr [n] se refiere al elemento arr [n + 1] en su DTor, puede tener problemas Sin embargo, fuera de mi cabeza, no puedo pensar en una situación del mundo real donde eso podría ser necesario. – foraidt

+0

@mxp. Completamente de acuerdo, pero si cada elemento de una matriz depende de al menos uno de los elementos de la matriz, el orden de destrucción de los elementos de la matriz será solo un problema menor. – jrbjazz

2

La información que usted se refiere en más eficaz C++ aplica a los objetos que contienen un par de otro objeto, como en este caso:

class Foo { 
    private: 
    Bar bar_1; 
    Bar bar_2; 

    public: 
    Foo() : bar_1(), bar_2() {} 
}; 

En el ejemplo anterior, se le han construido bar_1 primera , seguido de bar_2. Cuando un objeto de la clase Foo se destruye, primero se destruye bar_2, luego bar_1. A eso se refiere Scott Meyers.

Desde el punto de vista de la clase, una matriz de barras sería otro objeto que el compilador necesita destruir, por lo que el orden de destrucción afecta cuando la matriz se destruye en el contexto de los otros objetos de la clase.

En cuanto a qué orden se destruyen los elementos de una matriz, no me sorprendería demasiado si eso depende de la implementación. También tendrá la optimización desempeñando un papel aquí (por ejemplo, una matriz POD puede destruirse simplemente liberando su memoria, como puede ser un objeto que se compone únicamente de POD). Todo lo anterior puede afectar el orden en que se destruirán los elementos de una matriz.

Me interesaría saber por qué necesita saber el orden en que se destruyen los elementos de la matriz (aparte de la curiosidad técnica, que sería una razón válida en mi humilde opinión). Si es porque hay dependencias entre los elementos de la matriz, creo que la estructura de datos podría necesitar revisión.

1

Cualquier orden sería suficiente. Las dos opciones obvias son, por supuesto, en orden o en orden inverso. Sin embargo, en este caso, ninguno de los fabricantes de compiladores pensó que valdría la pena dejar esta implementación dependiente. Por lo tanto, la elección se hizo para ordenar el orden inverso (como señaló sharptooth, extendiendo el comportamiento habitual de LIFO)

0

No menciona a qué página del libro de Meyer se está refiriendo, pero estoy de acuerdo con Timo Geusch en que la explicación Parece que se refiere a que los constructores y los destructores se invocan de acuerdo con la herencia.

Para una matriz de instancias de objetos, el orden en que se destruyen los objetos es el inverso del orden de construcción. Esto es fácil de verificar, como muestra el siguiente código. Una variable de clase realiza un seguimiento del número total de instancias creadas, y un miembro de datos para cada objeto realiza un seguimiento de su propio número. El constructor y el destructor imprimen un mensaje, de modo que cuando se ejecuta podemos ver exactamente qué sucede y cuándo.

El código de prueba muestra el recuento de objetos de 0 a 9 al construir, luego de 9 a 0 al destruir las instancias. (Esto fue probado con g++-4.2 en Mac OS X.)

#include <iostream> 

class MyClass 
{ 
public: 

    MyClass() 
    { 
     mCounter = kInstanceCount++; 
     std::cout << "+++ MyClass() " << mCounter << std::endl; 
    } 

    ~MyClass() 
    { 
     std::cout << "--- MyClass() " << mCounter << std::endl; 
    } 

private: 
    unsigned   mCounter; 
    static unsigned  kInstanceCount; 
}; 

unsigned MyClass::kInstanceCount = 0; 

int main() 
{ 
    MyClass arr[10]; 
    return 0; 
} 

Usted tendría que comprobar el estándar de C++, como estoy 100% seguro de que esto no es un detalle de implementación (como suele ser el caso) , en cuyo caso no quiere confiar en este comportamiento.

Tenga en cuenta también que no es tan común crear una matriz basada en pila de instancias de objetos reales. Es más probable que esté usando std::vector, o tal vez usando punteros inteligentes para objetos asignados en el montón.

Cuestiones relacionadas