Cajero automatico

Iniciado por matver, 13 Marzo 2018, 13:51 PM

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

matver

Hola gente estoy aprendiendo POO con el problema del cajero automático. Me encuentro con el siguiente problema: Con setMonto inicio la cuenta en 2000, con SetRetiro quito de la cuenta 500 y hasta hay funciona bien pero cuando con SetDeposito intento agregar 100 a los 1500 que hasta hay estan en la cuenta cuando imprimo el saldo no son 1600 como yo creo sino que imprime 2100.


Código (cpp) [Seleccionar]

#include <iostream>
using namespace std;
class Cliente{
    public:

    void setMonto (int mm) {m=mm;}
    void setRetiro (int rr) {r=rr;}
    void setDeposito (int dd) {d=dd;}

   int getMonto(void) {
      return m;
}
   int getRetiro(void) {
      r=m-r;
        return r;
}
   int getDeposito(void) {
      d=m+d;
      return d;
}

private:

int m,r,d;
};

int main (void){
Cliente p1;
p1.setMonto(2000);
p1.setRetiro(500);
p1.setDeposito(100);
cout <<"El saldo es: "<<p1.getMonto()<<endl;
cout <<"El saldo es: "<<p1.getRetiro()<<endl;
cout <<"El saldo es: "<<p1.getDeposito()<<endl;

}





me funciona bien si modifico este metodo:
int getDeposito(void) {
       d=r+d;
       return d;
}
ahora la pregunta es,¿ si es correcto proceder así?

Serapis

#1
Hay propiedades que no deben ser de lectura y escritura...

Monto es un propiedad que requiere ser de lectura y escritura, pero deposito y retiro, deben serlo de solo escritura... esto es, una función única.


entero m

entero = propiedad lectura monto
 devolver m
fin propiedad
   propiedad escritrua Monto(entero valor)
       m= valor
   fin propiedad

funcion Retiro(entero valor)
  m -= valor
fin funcion

funcion Deposito(entero valor)
 m +=valor
fin funcion


Como ves es más sencillo...
Fíjate que si el valor a retirar es superior al monto, la cuenta quedará en números rojos...
Al caso podría añadirse funcionalidad para indicar si se permite retirar dejando la cuenta en números rojos o no, y si se permite números rojos si hay un límite...
Te pongo lo primero, y te dejo que tu realices lo segundo:


buleano rojo

buleano = propiedad PermitirCuentaNumerosRojos
   devolver rojo
fin propiedad
   propiedad PermitircuentaNumerosRojos(buleano r)
       rojo = r
   fin propiedad

// esto afecta a la función retiro. Ahora devuelve un buleano indicando si se efectuó o no el retiro, y el retiro sólo se lleva a cabo condicionado por la propiedad previa...
buleano = funcion Retiro(entero valor)
   si (rojo=TRUE)
       si (valor < m)
           m -=valor
           devolver TRUE
       sino
           devolver FALSE
       fin si
   sino
       m -= valor
       devolver TRUE
   fin si
fin funcion


Otra cosa es que puedas retener la última (ó x últimas) operaciones efectuadas...  por eso, comentado:
cout <<"El saldo es: "<<p1.getMonto()<<endl; <---- perfecto, OK
cout <<"El saldo es: "<<p1.getRetiro()<<endl; <---- carece de sentido
cout <<"El saldo es: "<<p1.getDeposito()<<endl; <---- carece de sentido

A cambio deberías teneruna propiedad llamada UltimaOperacion


entero ct
string op
string = Propiedad lectura UltimaOperacion
    devolver op
fin propiedad

entero = propiedad lectura UltimaCantidad
    devolver ct
fin propiedad

// y modificar lo previo...
...escritura monto(...)
    m = valor
    op = "Monto"
    ct = valor
fin propiedad

... Retiro( ... valor)
   m -= valor
   op = "Retiro
   ct = valor
fin funcion

... Deposito( ... valor)
    m += valor
    op = "Deposito"
    ct = valor
fin funcion

Ahora ya puedes consultar además del saldo, la última operación y el valor de dicha operación... nota que leer el saldo, no se considera una operación, porque nunca  modifica ningún valor (por el mero hecho de consultarse).

MAFUS

#2
No soy de C++, lo he visto de pincelada, lo mio es el C.

Pero a mi modo de ver el cliente solo debería guardar su saldo, aumentarlo o disminuirlo. Para más seguridad estas deberían ser incluso operaciones privadas a las que no se pudieran acceder desde ningún lugar, solo desde el cajero. Deberían ser funciones amigas.

El encargado de ingresar, retirar o ver el capital del cliente es el cajero y de éste dependen las reglas para hacerlo. Por ejemplo: si se intenta sacar más del capital que hay la operación falla.

Algo así:
Código (C++) [Seleccionar]
#include <iostream>
using namespace std;

class Cliente{
public:
   Cliente() {
       capital = 0;
   }

   double obtenerCapital() {
       return capital;
   }

   void ingreso(double cantidad) {
       capital += cantidad;
   }

   void retiro(double cantidad) {
       capital -= cantidad;
   }

private:
   double capital;
};

class Cajero {
public:
   Cajero() {
       _cliente = NULL;
   }

   void nuevoCliente(Cliente &cliente) {
       _cliente = &cliente;
   }

#define SI_HAY_CLIENTE() if(!_cliente) { \
   cout << "No hay un cliente definido para realizar esta accion." << endl; \
   return; } else ;

#define SI_TIENE_PERMISO(permiso, mensajeError) if(!permiso) { \
   cout << "Operacion denegada.\nRazon: " << mensajeError << "\n" << endl; \
   return; } else ;

   void ingreso(double cantidad) {
       bool permiso = true;
       string razon = "";

       SI_HAY_CLIENTE() {
           // Condiciones que permiten el ingreso. Si no es posible
           // hacer permiso false y rellenar la razón

           SI_TIENE_PERMISO(permiso, razon) {
               _cliente->ingreso(cantidad);
               cout << "Ingresados " << cantidad << " creditos.\n" << endl;
           }
       }
   }

   void retiro(double cantidad) {
       bool permiso = true;
       string razon = "";

       SI_HAY_CLIENTE() {
           // Condiciones que permiten el retiro. Si no es posible
           // hacer permiso false y rellenar la razón
           // Un ejemplo sería que no hubiera suficiente capital

           if(cantidad > _cliente->obtenerCapital()) {
               permiso = false;
               razon = "No hay capital suficiente para realizar esta operacion.";
           }

           SI_TIENE_PERMISO(permiso, razon) {
               _cliente->retiro(cantidad);
               cout << "Retirados " << cantidad << " creditos de la cuenta.\n" << endl;
           }
       }
   }

   void obtenerCapital() {
       SI_HAY_CLIENTE()
           cout << "Capital actual: " << _cliente->obtenerCapital() << " creditos.\n" << endl;
   }

#undef SI_TIENE_PERMISO
#undef HAY_CLIENTE

   void cerrarCliente() {
       _cliente = NULL;
   }

private:
   Cliente *_cliente;
};

int main() {
   Cliente p1;
   Cajero cajero;

   cajero.nuevoCliente(p1);

   cajero.ingreso(2000);
   cajero.retiro(500);
   cajero.obtenerCapital();
   cajero.ingreso(100);
   cajero.obtenerCapital();
   cajero.retiro(3000);
   cajero.obtenerCapital();
   cajero.cerrarCliente();
   cajero.obtenerCapital();

   return 0;
}