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.
#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í?
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, OKcout <<"El saldo es: "<<p1.getRetiro()<<endl;
<---- carece de sentidocout <<"El saldo es: "<<p1.getDeposito()<<endl;
<---- carece de sentidoA 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).
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í:
#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;
}