elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  C++ PUNTEROS a clases POO
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: C++ PUNTEROS a clases POO  (Leído 3,005 veces)
ianmorar03

Desconectado Desconectado

Mensajes: 43



Ver Perfil
C++ PUNTEROS a clases POO
« en: 6 Septiembre 2018, 10:10 am »

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:
Código
  1. #include <iostream>
  2. using namespace std;
  3. class persona{
  4. private:
  5.    string nom;
  6.    string id;
  7. public:
  8.    persona(){
  9.        nom=" ";
  10.        id=" ";
  11.    }
  12.    persona(string n,string i){
  13.        nom = n;
  14.        id=i;
  15.    }
  16.    string getNom(){
  17.        return nom;
  18.    }
  19.    string getId(){
  20.        return id;
  21.    }
  22.    void setNom(string n){
  23.        nom=n;
  24.    }
  25.    void setId(string i){
  26.        id=i;
  27.    }
  28.    ~persona(){
  29.        nom=" ";
  30.        id=" ";
  31.    }
  32. };
  33. class coleccion{
  34. private:
  35.    persona **p;
  36.    int cantidad;
  37. public:
  38.    coleccion(){
  39.        p=new persona*[10];
  40.        cantidad=0;
  41.    }
  42.    void ingresarPersona(persona *pe){
  43.        p[cantidad]=pe;
  44.        cantidad++;
  45.    }
  46.    persona devuelve(int i){
  47.        return *p[i];
  48.    }
  49.    ~coleccion(){
  50.        for(int i=0;i<cantidad;i++){
  51.            delete persona[i];
  52.        }
  53.        delete[] persona;
  54.    }
  55.  
  56. };
  57.  
  58. int main(){
  59.    coleccion *c = new coleccion;
  60.    persona *p1 = new persona("JUAN","12345");
  61.    persona *p2 =new persona("PEDRO","45678");
  62.  
  63.    c->ingresarPersona(p1);
  64.    c->ingresarPersona(p2);
  65.  
  66.    cout<<c->devuelve(0).getNom()<<endl; //muestra por pantalla "JUAN"
  67.    cout<<c->devuelve(1).getNom()<<endl; //muestra por pantalla "PEDRO"
  68.  
  69.    persona *p3; //hago una tercera persona
  70.    *p3 = c->devuelve(0); //le asigno los valores de la p1 a la p3
  71.    c->insertarPersona(*p3);
  72.  
  73.    cout<<c->devuelve(2).getNom()<<endl; //muestra por pantalla "JUAN"
  74.  
  75.    c->devuelve(2).setNom("CAMBIO");
  76.  
  77.    //se supone que solo cambia el nombre de p3
  78.    //pero cambia tambien el valor de p1
  79.  
  80.    cout<<c->devuelve(0).getNom()<<endl; //muestra por pantalla "CAMBIO"
  81.  
  82.  
  83.    system("PAUSE");
  84.    return 0;
  85. };
  86.  
  87.  
  88.  

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 :D


« Ú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


Desconectado Desconectado

Mensajes: 323


Ver Perfil WWW
Re: C++ PUNTEROS a clases POO
« Respuesta #1 en: 6 Septiembre 2018, 14:01 pm »

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:

Código
  1. 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

Aqui mi perfil en LinkedIn, invitame un cafe aqui
MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: C++ PUNTEROS a clases POO
« Respuesta #2 en: 6 Septiembre 2018, 14:51 pm »

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_COPIA

Aunque 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 Desconectado

Mensajes: 43



Ver Perfil
Re: C++ PUNTEROS a clases POO
« Respuesta #3 en: 6 Septiembre 2018, 17:55 pm »

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 :P
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 Desconectado

Mensajes: 1.603



Ver Perfil
Re: C++ PUNTEROS a clases POO
« Respuesta #4 en: 6 Septiembre 2018, 18:25 pm »

Desde mi ignorancia de C++ hice este código:

Código
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. class persona {
  6. private:
  7.    string nom;
  8.    string id;
  9.  
  10. public:
  11.    persona(){
  12.        nom="";
  13.        id="";
  14.    }
  15.  
  16.    persona(string n, string i) : nom(n), id(i) {}
  17.  
  18.    persona(const persona &p) : nom(p.nom), id(p.id) {} // Este copia sirve para objetos en stack
  19.  
  20.    persona(const persona *p) : nom(p->nom), id(p->id) {} // Este copia sirve para objetos en heap
  21.  
  22.    string getNom() {
  23.        return nom;
  24.    }
  25.  
  26.    string getId(){
  27.        return id;
  28.    }
  29.  
  30.    void setNom(string n){
  31.        nom = n;
  32.    }
  33.  
  34.    void setId(string i){
  35.        id = i;
  36.    }
  37. };
  38.  
  39. class coleccion{
  40. private:
  41.    persona *p[10];
  42.    int cantidad;
  43.  
  44. public:
  45.    coleccion() {
  46.        cantidad=0;
  47.    }
  48.  
  49.    void ingresarPersona(persona *pe) {
  50.        if(cantidad<10) {
  51.            p[cantidad]=pe;
  52.            cantidad++;
  53.        }
  54.    }
  55.  
  56.    persona* devuelve(int i) {
  57.        return p[i];
  58.    }
  59.  
  60.    ~coleccion() {
  61.        for(int i=0; i<cantidad; i++){
  62.            delete p[i];
  63.        }
  64.    }
  65. };
  66.  
  67. int main() {
  68.    coleccion *c = new coleccion;
  69.    persona *p1 = new persona("JUAN","12345");
  70.    persona *p2 = new persona("PEDRO","45678");
  71.  
  72.    c->ingresarPersona(p1);
  73.    c->ingresarPersona(p2);
  74.  
  75.    for(int i=0; i<2; ++i)
  76.        cout<<"c->devuelve("<<i<<")->getNom() = "<<c->devuelve(i)->getNom()<<"\n";
  77.    cout<<endl;
  78.  
  79.    persona *p3;
  80.    p3 = new persona(c->devuelve(0));
  81.    c->ingresarPersona(p3);
  82.  
  83.    for(int i=0; i<3; ++i)
  84.        cout<<"c->devuelve("<<i<<")->getNom() = "<<c->devuelve(i)->getNom()<<"\n";
  85.    cout<<endl;
  86.  
  87.    c->devuelve(2)->setNom("CAMBIO");
  88.  
  89.    for(int i=0; i<3; ++i)
  90.        cout<<"c->devuelve("<<i<<")->getNom() = "<<c->devuelve(i)->getNom()<<"\n";
  91.    cout<<endl;
  92. }
En línea

ianmorar03

Desconectado Desconectado

Mensajes: 43



Ver Perfil
Re: C++ PUNTEROS a clases POO
« Respuesta #5 en: 6 Septiembre 2018, 18:32 pm »

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

Desconectado Desconectado

Mensajes: 26



Ver Perfil WWW
Re: C++ PUNTEROS a clases POO
« Respuesta #6 en: 13 Septiembre 2018, 18:25 pm »

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í  :P
En línea

Ayudame en posicionamiento SEO en mi practica de la universidad : https://www.atorrijaoguachisnai.com/
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Clases en VB
Programación Visual Basic
Kizar 0 1,213 Último mensaje 17 Marzo 2006, 16:56 pm
por Kizar
Necesito muchas ideas sobre los usos de punteros y clases.
Programación C/C++
anonimo12121 2 1,937 Último mensaje 5 Marzo 2011, 20:03 pm
por anonimo12121
Duda Punteros Dobles/Array de punteros
Programación C/C++
MisterJava 2 4,905 Último mensaje 30 Diciembre 2012, 20:19 pm
por MisterJava
Punteros dobles / Punteros a puntero.
Programación C/C++
NOB2014 5 7,927 Último mensaje 13 Abril 2016, 16:00 pm
por MAFUS
(Consulta) Punteros a punteros en C
Programación C/C++
class_OpenGL 1 1,812 Último mensaje 19 Julio 2016, 14:29 pm
por class_OpenGL
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines