Autor
|
Tema: C++ PUNTEROS a clases POO (Leído 3,338 veces)
|
ianmorar03
Desconectado
Mensajes: 43
|
Tengo un problema a la hora de hacer un programa: Digamos que quiero insertar objetos dentro de una colección, y en el main, quiero hacer una copia de un objeto a otro, a la hora de cambiar los atributos del nuevo objeto(copia), se cambian los de la original, doy un ejemplo: #include <iostream> using namespace std; class persona{ private: string nom; string id; public: persona(){ nom=" "; id=" "; } persona(string n,string i){ nom = n; id=i; } string getNom(){ return nom; } string getId(){ return id; } void setNom(string n){ nom=n; } void setId(string i){ id=i; } ~persona(){ nom=" "; id=" "; } }; class coleccion{ private: persona **p; int cantidad; public: coleccion(){ p=new persona*[10]; cantidad=0; } void ingresarPersona(persona *pe){ p[cantidad]=pe; cantidad++; } persona devuelve(int i){ return *p[i]; } ~coleccion(){ for(int i=0;i<cantidad;i++){ delete persona[i]; } delete[] persona; } }; int main(){ coleccion *c = new coleccion; persona *p1 = new persona("JUAN","12345"); persona *p2 =new persona("PEDRO","45678"); c->ingresarPersona(p1); c->ingresarPersona(p2); cout<<c->devuelve(0).getNom()<<endl; //muestra por pantalla "JUAN" cout<<c->devuelve(1).getNom()<<endl; //muestra por pantalla "PEDRO" persona *p3; //hago una tercera persona *p3 = c->devuelve(0); //le asigno los valores de la p1 a la p3 c->insertarPersona(*p3); cout<<c->devuelve(2).getNom()<<endl; //muestra por pantalla "JUAN" c->devuelve(2).setNom("CAMBIO"); //se supone que solo cambia el nombre de p3 //pero cambia tambien el valor de p1 cout<<c->devuelve(0).getNom()<<endl; //muestra por pantalla "CAMBIO" system("PAUSE"); return 0; };
Cuando yo hago una copia del puntero, al cambiar los valores de la copia, cambian los de la original, como puedo solucionar este problema? Espero me hayan entendido
|
|
« Última modificación: 6 Septiembre 2018, 10:17 am por ianmorar03 »
|
En línea
|
Aquellos que estan locos como para pensar que pueden cambiar el mundo , son los que lo hacen.
|
|
|
CalgaryCorpus
|
Asi funcionan los punteros. Son guardadores de las direcciones de memoria de los objetos. El operador * y el operador -> no hacen mas que visitar las direcciones de memoria, por lo que cuando haces una copia de los punteros, solo haces copia de las direcciones, no de los objetos. Por la misma razon, cuando modificas usando el operador -> estas visitando el mismo objeto para los 2 punteros. Tener 2 punteros apuntando al mismo objeto se llama "alias" y esto que te ocurre es indicador de lo que ya te he explicado. Posible solucion: Crea un constructor de copia y usalo en vez de hacer una asignacion en las lineas 69 y 70. EL constructor de copia es un nuevo constructor que recibe un objeto del mismo tipo que la clase que estas creando. Finalmene, despues de implementar el constructor de copia y reemplazar esas 2 lineas, tu codigo se veria: persona *p3 = new persona(c->devuelve(0));
Sin ningun otro cambio necesario, deberia funcionar. Una convencion que no estas usando es nombrar las clases con mayuscula inicial, intenta seguirlo para hacer mas facil a otros leer tu codigo.
|
|
« Última modificación: 6 Septiembre 2018, 14:04 pm por CalgaryCorpus »
|
En línea
|
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
He intentado ejecutar tu código para ayudarte pero, aparte de la falta del constructor copia, faltan arreglar unos cuantos errores. No debería compilarte. Para saber qué es y qué hace un constructor copia pásate por aquí: http://c.conclase.net/curso/?cap=029#P29_COPIAAunque he de decirte que, ya que tus objetos están instanciados mediante new, en vez de recibir una referencia en el argumento (que también deberías incluir este constructor), deberás recibir un puntero.
|
|
|
En línea
|
|
|
|
ianmorar03
Desconectado
Mensajes: 43
|
Voy a averiguar mas sobre un constructor de copia y vere si funciona Las clases siempre las uso en mayúsculas, y este código ni siquiera se si compila, lo hice lo mas rapido y sencillo para que me entendieran El codigo original es mas complicado, y tiene mucho mas cosas gg Pero muchas gracias de antemano a los 2, @MAFUS y @CalgaryCorpus
|
|
|
En línea
|
Aquellos que estan locos como para pensar que pueden cambiar el mundo , son los que lo hacen.
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
Desde mi ignorancia de C++ hice este código: #include <iostream> using namespace std; class persona { private: string nom; string id; public: persona(){ nom=""; id=""; } persona(string n, string i) : nom(n), id(i) {} persona(const persona &p) : nom(p.nom), id(p.id) {} // Este copia sirve para objetos en stack persona(const persona *p) : nom(p->nom), id(p->id) {} // Este copia sirve para objetos en heap string getNom() { return nom; } string getId(){ return id; } void setNom(string n){ nom = n; } void setId(string i){ id = i; } }; class coleccion{ private: persona *p[10]; int cantidad; public: coleccion() { cantidad=0; } void ingresarPersona(persona *pe) { if(cantidad<10) { p[cantidad]=pe; cantidad++; } } persona* devuelve(int i) { return p[i]; } ~coleccion() { for(int i=0; i<cantidad; i++){ delete p[i]; } } }; int main() { coleccion *c = new coleccion; persona *p1 = new persona("JUAN","12345"); persona *p2 = new persona("PEDRO","45678"); c->ingresarPersona(p1); c->ingresarPersona(p2); for(int i=0; i<2; ++i) cout<<"c->devuelve("<<i<<")->getNom() = "<<c->devuelve(i)->getNom()<<"\n"; cout<<endl; persona *p3; p3 = new persona(c->devuelve(0)); c->ingresarPersona(p3); for(int i=0; i<3; ++i) cout<<"c->devuelve("<<i<<")->getNom() = "<<c->devuelve(i)->getNom()<<"\n"; cout<<endl; c->devuelve(2)->setNom("CAMBIO"); for(int i=0; i<3; ++i) cout<<"c->devuelve("<<i<<")->getNom() = "<<c->devuelve(i)->getNom()<<"\n"; cout<<endl; }
|
|
|
En línea
|
|
|
|
ianmorar03
Desconectado
Mensajes: 43
|
Ahora que recuerdo, creo haber visto el constructor de copia en clases y no estaba prestando atención jaja Utilizare el de copia para dinamico, que estoy utilizando Dinamicos en mi programa
|
|
« Última modificación: 16 Septiembre 2018, 01:36 am por #!drvy »
|
En línea
|
Aquellos que estan locos como para pensar que pueden cambiar el mundo , son los que lo hacen.
|
|
|
Mr.Moonlight
|
Siempre que estés trabajando con una clase que use punteros , los más recomendable es crear siempre constructor de copia y sobrecargar el operador de asignación para evitar este tipo de problemas o al menos yo siempre lo entendí así
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Clases en VB
Programación Visual Basic
|
Kizar
|
0
|
1,327
|
17 Marzo 2006, 16:56 pm
por Kizar
|
|
|
Necesito muchas ideas sobre los usos de punteros y clases.
Programación C/C++
|
anonimo12121
|
2
|
2,157
|
5 Marzo 2011, 20:03 pm
por anonimo12121
|
|
|
Duda Punteros Dobles/Array de punteros
Programación C/C++
|
MisterJava
|
2
|
5,212
|
30 Diciembre 2012, 20:19 pm
por MisterJava
|
|
|
Punteros dobles / Punteros a puntero.
Programación C/C++
|
NOB2014
|
5
|
8,473
|
13 Abril 2016, 16:00 pm
por MAFUS
|
|
|
(Consulta) Punteros a punteros en C
Programación C/C++
|
class_OpenGL
|
1
|
2,046
|
19 Julio 2016, 14:29 pm
por class_OpenGL
|
|