Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: anonimo12121 en 12 Marzo 2011, 00:51 am



Título: El último post el que esta abajo. ->
Publicado por: anonimo12121 en 12 Marzo 2011, 00:51 am
al introducir nombre se me cierra el programa y no lo entiendo.


Código:
#include <iostream>
using namespace std;
class base {
    private:
        char *nombre;
        char *tlf;
    public:
        base();
        void delname();
        void deltlf();
        void dnuevo();
        void view();
};
base::base(){
    nombre="\0";
    tlf="\0";
};
void base::delname(){
    
};
void base::deltlf(){
    
};
void base::dnuevo(){
    cout << "\nIntroduce un nombre: " ;
    cin >> nombre;
    cout << "\nIntroduce un telefono: ";
    cin >> tlf;
};
void base::view(){
    cout << "---------------------------------------------------------" << endl;
    cout << "Nombre: " << nombre << endl;
    cout << "Tlfn: " << tlf << endl;
    cout << "---------------------------------------------------------" << endl;
    cout << "1-Nuevo\t2-Eliminar 3-Salir" << endl;
};

int main(int argc,char *argv[]){
    base b[10];
    int pag=0;
    int evento=0;
    int pagmax=0;
    while(1){
        b[pag].view();
        cout << "Opcion: ";
        cin >> evento;
        if(evento==1){
            pagmax=pagmax+1;
            b[pagmax].dnuevo();
        }
        else if(evento==2);
        else if(evento==3)break;
        evento=0;
    }
    cin.get();
    return 0;
}


Título: Re: No entiendo por que se me cierra el programa
Publicado por: Akai en 12 Marzo 2011, 01:22 am
Seguramente te esté dando una violación de segmento por lo siguiente:
Código
  1.  
  2. char *nombre;
  3. char *tlf

constructor:
Código
  1. nombre="\0";
  2. tlf="\0";
  3.  

No les das tamaño.


Título: Re: No entiendo por que se me cierra el programa
Publicado por: anonimo12121 en 12 Marzo 2011, 01:29 am
Seguramente te esté dando una violación de segmento por lo siguiente:
Código
  1.  
  2. char *nombre;
  3. char *tlf

constructor:
Código
  1. nombre="\0";
  2. tlf="\0";
  3.  

No les das tamaño.
Por favor akai dime que se supone que debo de poner.


Título: Re: No entiendo por que se me cierra el programa
Publicado por: Akai en 12 Marzo 2011, 02:10 am
o bien declaras nombre y tlf como

Código
  1. char nombre[20]
  2. char tlf[10]

o algo así, y en el constructor no haces nada, o bien, dejas la declaración como puntero y en el constructor haces lo siguiente:
Código
  1. nombre=new char[20] //o tu tamaño
  2. tlf=new char[10]//o tu tamaño

En principio, si luego vas a leer una cadena, no necesitas asignarles el \0.

Por otro lado, en C++, a menos que trabajes con la clase string, que no es lo mismo que trabajar con char[] o char* no puedes hacer que nombre="\0" o tlf="\0". Sino que has de asignar caracter a caracter o copiar con funciones. Además, la cadena vacía es "" no "\0".


Título: Re: Alaa punteraco con clase
Publicado por: anonimo12121 en 12 Marzo 2011, 11:25 am
ok gracias.

EDITO: Para no crear un post tonto...
Díganme si el uso que le he dado a un puntero que apunta a una clase en la función bubble está bien hecho o no se debería de hacer así por favor.
Código
  1. #include <iostream>
  2. using namespace std;
  3. class base {
  4.    private:
  5.        bool rellena;//0 no tiene contenido . 1 tiene contenido
  6.        char *nombre;
  7.        char *tlf;
  8.    public:
  9.        base();
  10.        void del();
  11.        void dnuevo();
  12.        void editar();
  13.        void view(int n);
  14.        void freeram();
  15. };
  16. base::base(){
  17.    rellena = false;
  18.    nombre = new char[20];
  19.    tlf = new char[20];
  20. };
  21. void base::del(){
  22. };
  23. void base::dnuevo(){
  24.    cout << "\nIntroduce un nombre: " ;
  25.    cin >> nombre;
  26.    cout << "\nIntroduce un telefono: ";
  27.    cin >> tlf;
  28.    rellena=true;
  29. };
  30. void base::freeram(){
  31.    delete[] nombre;
  32.    delete[] tlf;
  33. };
  34. void base::editar(){
  35.    dnuevo();
  36. };
  37. void base::view(int n){
  38.    cout << "---------------------------------------------------------" << endl;
  39.    cout << "Nombre: ";
  40.    if(rellena==true)cout << nombre;
  41.    cout << endl;
  42.    cout << "Tlfn: ";
  43.    if(rellena==true)cout << tlf ;
  44.    cout << endl;
  45.    cout << "---------------------------------------------------------" << endl;
  46.    cout << "1-Nuevo\t2-Eliminar 3-Salir 4-Editar 8-Pagback 9-Pagnext\t Pag: " << n << endl;
  47. };
  48. void bubble(int n1,int n2,base b[]){
  49.    base *p;
  50.    for(int i=n1;i<n2;i++){
  51.        p=&b[i+1];
  52.        b[i]=*p;
  53.    }
  54. };
  55.  
  56. int main(int argc,char *argv[]){
  57.    base b[10];
  58.    int pag=1;
  59.    int evento=0;
  60.    int pagmax=0;
  61.    while(1){
  62.        b[pag].view(pag);
  63.        cout << "Opcion: ";
  64.        cin >> evento;
  65.        if(evento==1){
  66.            pagmax=pagmax+1;
  67.            pag=pagmax;
  68.            b[pag].dnuevo();
  69.        }
  70.        else if(evento==2){
  71.            if(pag!=1){
  72.                bubble(pag,pagmax,b);
  73.                pagmax--;
  74.            }
  75.        }
  76.        else if(evento==3)break;
  77.        else if(evento==4)b[pag].editar();
  78.        else if(evento==8 && pag>1)pag--;
  79.        else if(evento==9 && pag < pagmax)pag++;
  80.        evento=0;
  81.        cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" ;
  82.    }
  83.    for(int i=0;i<10;i++)b[i].freeram();
  84.    cout << "El programa se cerrara" << endl;
  85.    cin.get();
  86.    return 0;
  87. }

Saludos


Título: Re: El último post el que esta abajo. ->
Publicado por: satu en 12 Marzo 2011, 18:20 pm
Hola

Para lo que quieres hacer debes sobrecargar el operador =

Código
  1. base operator = (const base &b);
  2.  

Código
  1. base base::operator = (const base &b)
  2. {
  3.    rellena = b.rellena;
  4.    strcpy(nombre, b.nombre);
  5.    strcpy(tlf, b.tlf);
  6. }
  7.  

De esta forma en la función bubble te quedaría

Código
  1. void bubble(int n1,int n2,base b[]){
  2.    for(int i=n1;i<n2;i++)
  3.        b[i]=b[i+1];
  4. }
  5.  

Saludos


Título: Re: El último post el que esta abajo. ->
Publicado por: anonimo12121 en 12 Marzo 2011, 23:12 pm
Hola

Para lo que quieres hacer debes sobrecargar el operador =

Código
  1. base operator = (const base &b);
  2.  

Código
  1. base base::operator = (const base &b)
  2. {
  3.    rellena = b.rellena;
  4.    strcpy(nombre, b.nombre);
  5.    strcpy(tlf, b.tlf);
  6. }
  7.  

De esta forma en la función bubble te quedaría

Código
  1. void bubble(int n1,int n2,base b[]){
  2.    for(int i=n1;i<n2;i++)
  3.        b[i]=b[i+1];
  4. }
  5.  

Saludos
y a que se debe que me de buen resultado?


Título: Re: El último post el que esta abajo. ->
Publicado por: satu en 13 Marzo 2011, 18:16 pm
Hola

Pues se debe a que le estás diciendo al compilador cómo asignar los objetos de esa clase. Date cuenta que cuando asignas enteros el compilador sabe qué tiene que hacer, pero cuando se encuentra con objetos de la clase "base" o de cualquier clase tienes que decírselo tú.

Saludos


Título: Re: El último post el que esta abajo. ->
Publicado por: anonimo12121 en 13 Marzo 2011, 18:26 pm
Ose lo que debo de hacer es darle a cada miembro su valor uno a uno.
Esque pensaba que lo que hacia al hacerlo con la clase directa lo hacia todo.


Título: Re: El último post el que esta abajo. ->
Publicado por: satu en 13 Marzo 2011, 21:21 pm
Eso es lo primero que se piensa por la costumbre de la asignación de enteros y otros tipos simples pero con objetos "no funciona" porque no sabes qué va a hacer el compilador.

El problema de la forma en que tú lo has hecho es que no has reservado memoria para p entonces te peta, aparte de que el operador = no lo has definido.

Lee sobre la sobrecarga de operadores porque es muy útil, entre otras cosas para ordenar los elementos o compararlos con <, >, ==, != o imprimir con cout, etc

Saludos


Título: Re: El último post el que esta abajo. ->
Publicado por: Akai en 13 Marzo 2011, 21:30 pm
En principio, la importancia de sobrecargar el operador de asignación o de realizar un constructor de copia en una clase viene por lo siguiente:

(Dependiendo del compilador, pero en principio)
Si no están definidos, se copia campo a campo.

Problema? Si tienes memoria dinámica, y copias campo a campo, tienes dos punteros apuntando al mismo sitio. La copia es borrada (por ejemplo, pasabas por copia en una función) y con ello se libera la memoria dinámica a la cual apuntaba. Ahora, el original tiene un campo que apunta a un espacio liberado, mala suerte, violación de segmento cuando accedas y fin del programa.

Solución? constructores de copia y sobrecarga de operadores de asignación, para en caso que tu clase trabaje con memoria dinámica, replicar dicha memoria de forma manual, y no copiando el puntero. (por ejemplo, volviendo a declarar un vector y copiando todos los elementos manualmente, en vez que el compilador simplemente te copie el puntero).