Destructor se ejecuta bien pero da error al final de la ejecución [SOLUCIONADO]

Iniciado por SARGE553413, 25 Abril 2013, 14:05 PM

0 Miembros y 1 Visitante están viendo este tema.

SARGE553413

Hola a todos.

Tengo una clase plantilla que como atributos tiene una matriz (T **m) y 2 enteros
(int m, int n). (Defino así la matriz porque si no el compilador me da fallo, creo que por el parámetro, tampoco me deja haciendo T *x[])
He leído que para clases que tienen atributos que son mas complejos que vectores (matrices, grafos etc) hay que definir el destructor porque éste por si solo no sabe que hacer ante dichas estructuras.
El caso es que lo estoy intentando implementar pero haga lo que haga siempre me da error, esto lo que he hecho, y no entiendo por qué no funciona:


private:
     T **x;
     int m,n;
     //.......
     //.......
public:
      A::~A()
     //.......
     //.......
template <class T>
A::~A(){
for(int i=0;i<this->m;i++){
delete[](this->x[i]);
}
delete[]this->x;
delete& this->m;
delete& this->n;
}


¿Como habría que hacerlo?

Muchas gracias.

NoLife

#1
bueno, esta es la sintaxis básica del constructor y destructor:

class A
{
public:
      // Constructor
      A()
      {
           // codigo
      }
     
      // Destructor
      ~A()
      {
           //codigo: de lo usual para liberar espacio reservado en memoria.
      }

};

Creo que basicamente tu problema es el operador de resolucion( : : ), que estas usandolo incorrectamente. El Operador de resolucion es para hacer llamados, por ejemplo: A::E(): significa que llamas a la funcion E en el contexto A.
"Cualquier tonto puede escribir código que la PC entienda. Los buenos programadores escriben código que los humanos pueden entender." – Martin Fowler

SARGE553413

#2
Pero si utilizas fichero de cabecera *.h y de codigo fuente *.cpp tienes que usar el operador de ámbito en el código fuente.

De todas formas probaré, vuelvo y escribo.


EDITO.

Si, si quito el operador de ámbito el compilador me dice que estoy declarando el método como no miembro.

Voy a clarificar la estructura del documento, está todo en un *.h porque si lo haces por separado no puedes usar templates:


#ifndef A_H
#define A_H 1

template <class T>
class A{
//atributos
  private: ...
//delcaración de métodos
  public:....
};

#endif

template <class T>
A::~A(){
  //codigo descrito arriva
}

//resto de métodos
...
...


Nota: lo mas acojonante es que si dejo el destructor vacío (sin código), al intentar hacer delete a un objeto clase A, me salta el mismo error siempre.
El error es, haga lo que haga el destructor, termina, porque escribo
cout<<"1"<<endl;' al principio y 'cout<<2..' al final y salen por pantalla los 2, el error es que el programa "no responde" justo antes de hacer el 'return 0' del main.

Nota2: he probado a declarar un puntero normal y hacerle delete y en ese caso el destructor si funciona bien.
Entonces pregunto, como se define un destructor de matrices, y saber si tenemos una clase con punteros y con variables normales, el destructor debe destruir solo los punteros, o también las variables normales.

NoLife

bueno, si tampoco eso funciono... espero te ayude otro. yo soy algo nuevo. saludos. hehe
"Cualquier tonto puede escribir código que la PC entienda. Los buenos programadores escriben código que los humanos pueden entender." – Martin Fowler

SARGE553413


SARGE553413

Vale he encontrado el problema.

Resulta que el objeto clase A lo había declarado "no puntero", como el compilador me decía que delete está esperando puntero le paso la dirección de memoria del objeto, es decir:

...
A a(5);
delete &a;
....


Si declaro un puntero no me da ese problema, y creo que se por qué:

Al declararse 'a' como objeto "no puntero" no es persistente, es decir, al terminar el método main se destruye automáticamente. Por tanto, si hacemos 'delete &a', está bien hecho, el problema es que al terminar el main automáticamente se llama a los destructores de objetos para ser borrados.
Por eso mi destructor funcionaba bien, pero sin yo saberlo, esta siendo llamado 2 veces para detruir el mismo objeto.
Ahora he puesto en cuerpo del destruc. 'cout<<"Destructor"<<endl', he declarado 2 objetos a, y *b (puntero), he hecho solo delete al b (habiéndolo construido previamente claro) y he comprobado que el destructor es llamado 2 veces, explícitamente para b e implícitamente para a.
Solucionado, espero le sirva a alguien.
Saludos.

PD. si alguien me dice como poner spoiler en este foro, subo todo el código (main y clase) para que lo veáis.