PDA

Ver la versión completa : [Ayuda] Error en C++ borrando un array de objetos dinamicos.



The_Punisher
22/06/2015, 12:01
Buenas gente!

Estoy empezando con C++ y voy leyendo un libro y haciendo ejercicios, pero me he quedado aquí un poco atascado y no encuentro exactamente una solución a este error.

Es en la última línea al intentar borrar el array, igual es una tontería pero no se que estoy haciendo mal.

A ver si me podeís echar una mano, un saludo!



#include <iostream>

using namespace std;

class Telefono {
string numero;
float importe;
string tarifa;
string nombre;

public:
Telefono (); //constructor por defecto
Telefono (string _numero); //constructor parametrizado
Telefono (const Telefono &tel);
Telefono (string _numero, string _tarifa, string _nombre);
void mostrar();
~Telefono (); //destructor
void actualizarImporte(int _importe);
void mostarImporte();
float obtenerImporte();

};


Telefono::Telefono () {
importe = 0;
numero="985541318";
cout <<"Constructor por defecto"<<endl;
}

Telefono::Telefono (string _numero) {
numero=_numero;
importe=0;
cout <<"Constructor parametrizado"<<endl;
}

Telefono::Telefono (string _numero, string _tarifa, string _nombre) {
numero=_numero;
tarifa=_tarifa;
nombre=_nombre;
importe=0;
cout <<"Constructor parametrizado"<<endl;
}

Telefono::Telefono (const Telefono &tel) {
importe=tel.importe;
cout <<"Constructor copia"<<endl;
}

void Telefono::mostrar() {
cout<<"Numero :"<<numero<<endl;
}

void Telefono::mostarImporte(){
cout<<"Importe: "<<importe<<endl;
}

void Telefono::actualizarImporte(int _importe){
importe=_importe;
}
float Telefono::obtenerImporte(){
return importe;
}

Telefono::~Telefono () {
cout <<"Destructor"<<endl;
}

int main() {

Telefono telefono1;
Telefono telefono2("927123456");
Telefono *telefono3 = new Telefono("927123456", "Di", "Juan");

telefono3->mostarImporte();
telefono3->actualizarImporte(30);
telefono3->mostarImporte();

telefono1.mostrar();
telefono2.mostrar();
telefono3->mostrar();

telefono1.mostrar();
telefono2.mostrar();

Telefono *telefono4[2];
telefono4[0] = new Telefono("927654321", "No", "María Paz");
telefono4[0]->actualizarImporte(20);

cout << "Importe: " << telefono4[0]->obtenerImporte() << endl;
telefono4[0]->mostrar();
telefono4[1] = new Telefono("927555555", "No", "Jesús Sanz");
telefono4[1]->actualizarImporte(50);
cout << "Importe: " << telefono4[1]->obtenerImporte() << endl;
telefono4[1]->mostrar();
telefono4[0]->mostrar();
telefono4[1]->mostrar();

cout<<"Hola telefono 3"<<endl;
delete telefono3;
cout<<"Adios telefono 3"<<endl;
cout<<"Hola telefono 4"<<endl;
delete[] telefono4; //Aquí casca :(
cout<<"Adios telefono 4"<<endl;
}

swapd0
22/06/2015, 12:06
Telefono4 es un array de dos punteros, debes borrar los elementos del array pero no el array porque no has creado el array de forma dinamica. No se si me explico.
delete telefonoπ4[0];
delete telefonoπ4[1];
// despues aunque no hace falta pero los puedes asignar a NULL o nullptr (c++11)

The_Punisher
22/06/2015, 12:11
Eso había hecho, y funcionaba, los destruía perfectamente.

Sin llevarte la contraría no entiendo porque dices que no he creado el array de forma dinámica, el libro dice que así lo creo de forma dinámica y debería poder borrarlo así.

¿Cómo sería entonces la implementación correcta?

swapd0
22/06/2015, 12:51
Los objetos que crees con un new se destruyen con delete, y el array no estaba creado con un new...
Si quieres crear el array de forma dinámica seria así, pero en este ejemplo los elementos del array son objetos teléfono y no punteros a objetos teléfono (hay que usar . en vez de -> y quitar los new en las asignaciones)


Telefono *telefono4 = newTelefono[2];
telefono4[0] = Telefono("927654321", "No", "María Paz");
telefono4[0].actualizarImporte(20);

cout << "Importe: " << telefono4[0].obtenerImporte() << endl;
telefono4[0].mostrar();
telefono4[1] = Telefono("927555555", "No", "Jesús Sanz");
telefono4[1].actualizarImporte(50);
cout << "Importe: " << telefono4[1].obtenerImporte() << endl;
telefono4[1].mostrar();
telefono4[0].mostrar();
telefono4[1].mostrar();

cout<<"Hola telefono 3"<<endl;
delete telefono3;
cout<<"Adios telefono 3"<<endl;
cout<<"Hola telefono 4"<<endl;
delete[] telefono4;
cout<<"Adios telefono 4"<<endl;


-----Actualizado-----

Aqui con un array (dinamico) de punteros a Telefono.




Telefono **telefono4;
telefono4 = new Telefono*[2];
telefono4[0] = new Telefono("927654321", "No", "María Paz");
telefono4[0]->actualizarImporte(20);

cout << "Importe: " << telefono4[0]->obtenerImporte() << endl;
telefono4[0]->mostrar();
telefono4[1] = new Telefono("927555555", "No", "Jesús Sanz");
telefono4[1]->actualizarImporte(50);
cout << "Importe: " << telefono4[1]->obtenerImporte() << endl;
telefono4[1]->mostrar();
telefono4[0]->mostrar();
telefono4[1]->mostrar();

...
delete[] telefono4; // solo se esta borrando el array y no los objetos que contiene!!!!


-----Actualizado-----



Sin llevarte la contraría no entiendo porque dices que no he creado el array de forma dinámica, el libro dice que así lo creo de forma dinámica y debería poder borrarlo así.

El array no esta creado de forma dinámica, los objetos que contienen si. Por eso hay que borrar los objetos pero no el array.



¿Cómo sería entonces la implementación correcta?
No se, la que funcione. XD

-----Actualizado-----

La ventaja de estas dos ultimas versiones que he puesto (las del array dinamico) es que puedes cambiar el 2 por una variable y cambiar el tamaño en tiempo de ejecución, la version que tu pusiste el tamaño se debe saber en tiempo de compilación.

De todas formas en estos casos es mejor usar algun contenedor de las STL, pero eso mas adelante.

The_Punisher
26/06/2015, 18:44
Perfecto, me has solucionado la duda. En el libro venía tal cual y me llevo a confusión.

Muchísimas gracias por la explicación :)

Logann
27/06/2015, 16:32
Como te ha dicho swap, es importante entender new y delete, pero en c++ tienes que intentar escribir codigo sin news e incluso sin punteros. Siempre que se pueda es mejor tener un constructor por defecto.

swapd0
27/06/2015, 18:28
Matizando.

Sin punteros no funciona la vinculacion dinamica en C++.

Si no tiene sentido tener un constructor por defecto la clase no debería tener uno, a no ser de que necesites meter objetos en un contenedor de las STL que te obliga a tener un constructor por defecto.

hardyx
28/06/2015, 16:59
Básicamente es así:
New de array, delete de array. New simple, delete simple.
Y con objetos se usa el constructor al hacer el new.

Con arrays:

// new de array
int *numeros = new int[5];

// usar el array
numeros[3] = 23;

// delete de array
delete[] numeros;

Con tipos básicos:


// new simple con tipo básico
int *num = new int;

// usar el puntero
*num = 23;

// delete simple
delete num;

Con objetos:

// new con objetos y constructor
Coche *coche = new Coche();

// usar el objeto
coche->SetPuertas(4);

// delete simple
delete coche;

Logann
28/06/2015, 21:20
Donde he dicho constructor quería decir destructor, en referencia a no utilizar memoria dinámica manualmente.