Foros del Web » Programación para mayores de 30 ;) » Programación General »

algun experto en c++?

Estas en el tema de algun experto en c++? en el foro de Programación General en Foros del Web. tengo un problemilla, tengo hecha una clase pago para una tienda virtual class pago { private: float cantidad; public: pago(float); ~pago(); }; por ejemplo cuando ...
  #1 (permalink)  
Antiguo 17/04/2005, 10:08
 
Fecha de Ingreso: junio-2004
Mensajes: 283
Antigüedad: 20 años, 5 meses
Puntos: 0
algun experto en c++?

tengo un problemilla, tengo hecha una clase pago para una tienda virtual

class pago
{
private:
float cantidad;

public:
pago(float);
~pago();

};

por ejemplo cuando la llamo lo hago así, desde otra clase:
void Venda::hacerpago(float dinero)
{ppago = new pago (dinero);
}

Pues ahora viene lo que no entiendo, y es que tengo que hacer que pago sea clase abstracta para que acepte pago en efectivo y pago por tarjeta.. pero no se por donde empezar a redefinir...y como seria luego para llamar a las clases

alguna ayuda?

graaacias ;)
__________________
pOrtfOliO
  #2 (permalink)  
Antiguo 17/04/2005, 10:22
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años, 7 meses
Puntos: 17
Cita:
Iniciado por custo
tengo un problemilla, tengo hecha una clase pago para una tienda virtual

class pago
{
private:
float cantidad;

public:
pago(float);
~pago();

};

por ejemplo cuando la llamo lo hago así, desde otra clase:
void Venda::hacerpago(float dinero)
{ppago = new pago (dinero);
}

Pues ahora viene lo que no entiendo, y es que tengo que hacer que pago sea clase abstracta para que acepte pago en efectivo y pago por tarjeta.. pero no se por donde empezar a redefinir...y como seria luego para llamar a las clases

alguna ayuda?

graaacias ;)
Mmm, sonsacando de todo lo que has puesto, lo único que saco es:
-Quieres tener 1 clase abstracta pura "pago", que se deriva en "pago con dinero", "pago con tarjeta".
- "Pago" tiene dos entradas, de "dinero" y de "tarjeta".

Acláralo.
  #3 (permalink)  
Antiguo 17/04/2005, 10:30
 
Fecha de Ingreso: junio-2004
Mensajes: 283
Antigüedad: 20 años, 5 meses
Puntos: 0
sí, eso mismo! lo que ando un poco perdido con esto

gracias!
__________________
pOrtfOliO
  #4 (permalink)  
Antiguo 17/04/2005, 10:33
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años, 7 meses
Puntos: 17
Cita:
Iniciado por custo
sí, eso mismo! lo que ando un poco perdido con esto

gracias!
No, te digo que me digas cuál de esas dos. No son iguales >_>!!
  #5 (permalink)  
Antiguo 17/04/2005, 10:40
 
Fecha de Ingreso: junio-2004
Mensajes: 283
Antigüedad: 20 años, 5 meses
Puntos: 0
ops perdon, tienes razon! ^_^

tendria q hacer una clase abstracta pago y una subclase pagoenefectivo y pagocontarjeta para despues llamar una u otra en funcion de lo qe elija el cliente en el programa principal.

Gracias por tu ayuda! ;)
__________________
pOrtfOliO
  #6 (permalink)  
Antiguo 17/04/2005, 10:50
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años, 7 meses
Puntos: 17
Cita:
Iniciado por custo
ops perdon, tienes razon! ^_^

tendria q hacer una clase abstracta pago y una subclase pagoenefectivo y pagocontarjeta para despues llamar una u otra en funcion de lo qe elija el cliente en el programa principal.

Gracias por tu ayuda! ;)

Bien :) Es sencillo. Supongo que un "pago" nunca debería realizarse sin un "medio" (sea dineo, sea tarjeta, sea gallina de los huevos de oro). Así que te la declaro pura (= no se puede crear instancias de esa clase a secas).

Código:
class pago
{
public:
    pago(float const cantidad) : Cantidad(cantidad);
    virtual ~pago() = 0;

private:
    float const Cantidad;

// ...
};


class pago_dinero : public pago
{
public:
    pago_dinero(float const cantidad) : pago(cantidad);
    ~pago_dinero();
// ...
};

class pago_tarjeta : public pago
{
public:
    pago_tarjeta(float const cantidad) : pago(cantidad);
    ~pago_tarjeta ();
// ...
};
A mi juicio creo que eso es lo que pretendes. En cualquier caso, con ese sistema tienes que dar a fin de cuentas un precio en los contructores... (sea de dinero o de tarjeta).

Puede usarlo así:

Código:
{
pago p0(5555); // Error de compilación, no puedes declarar un simple "pago"
pago_dinero p1(1000); // Pagas 1000 con dinero
pago_tarjeta p2(9999); // Me timan mucho más si llevo la visa
}
Ésto solo lo veo útil si quieres hacer diferencias, logs, otras acciones o pedir por ejemplo la ID de la tarjeta (así la pides en el constructor...) en las clases derivadas. Si no, a mi parecer debería ir en una clase más general como una función simple.
  #7 (permalink)  
Antiguo 17/04/2005, 10:58
 
Fecha de Ingreso: junio-2004
Mensajes: 283
Antigüedad: 20 años, 5 meses
Puntos: 0
Muchas gracias! era más fácil de lo que pensaba! Te puedo preguntar algunas cosas que no entiendo?
Como es que haces la declaración de la constructora así? Obedece a algo en especial?

Código:
class pago{
public:
    pago(float const cantidad) : Cantidad(cantidad);
es que yo siempre lo habia visto asi:

Código:
class pago{
public:
    pago(float const cantidad);
Y otra cosilla, solo se declara como virtual la destructora, y la constructora no?

Código:
virtual ~pago() = 0;

Gracias, me ha venido de perlas, ahora voy a aplicarlo a mi código!
__________________
pOrtfOliO
  #8 (permalink)  
Antiguo 17/04/2005, 12:42
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años, 7 meses
Puntos: 17
Veamos:

Código:
pago(float const cantidad) : Cantidad(cantidad);
Por explicarlo fácilmente, eso asigna a la __constante__ Cantidad de la clase (private) el valor del parámetro. Dentro del código del constructor es mejor poner eso que:

Código:
pago::pago(float const cantidad)
{
    Cantidad = cantidad;
}
Primero, porque es mucho más efectivo. Segundo, porque permite asignar el valor a la constante (tienes asegurado que la cantidad no va a cambiar nunca). También puedes hacerlo aunque no sea constante.


Código:
virtual ~pago() = 0;
Eso es para establecer que la clase es virtual - forzar polimorfismo - (virtual) y pura (= 0). Se coloca muchas veces en el destructor para no ponerlo en otras funciones. Realmente al destructor no le afecta.


El destructor derivado siempre se va a llamar antes que el base. Si tienes una caja llena de bombones, luego metes una madera y encima los caramelos. Para volver "hacia" atrás, debes sacar los caramelos, luego la madera y luego los bombones. En resumen: se llama primero al destructor derivado, luego al base. Pero eso es automático y _no tiene que ver_ con "virtual" o "= 0".


Para que te aclares, lo de "virtual" y "= 0 " no "va" con los constructores/destructores. Se coloca en el destructor para no tener que usar una función basura que simplemente tenga esos atributos.



Un constructor es lo mismo. Siempre se llamará al derivado y luego al base. Para hacerlo, se usa:

Código:
pago_dinero(float const cantidad) : pago(cantidad);
Eso lo que hace es llamar al constructor de la clase base "pago(float)" y le pasa como argumento el mismo que el que le has pasado (dado que lo lógico es que si realizas un pago el dinero que pongas será el mismo que si lo haces con dinero, por lo menos el dinero "dado", sin impuestos ). Por eso te sugerí que en ese contructor también puedes implementar (y es la utilidad en este caso que veo) algo así:

Código:
pago_tarjeta(float const cantidad, tarjeta tar) : pago(cantidad);
En el código de la función lees la tarjeta, cobras los impuestos... Lo que sea, y encima sin alterar otro tipo de pagos (como el del dinero a secas). Así, harías (es un simple ejemplo):

Código:
{
	int precio = 1000;
	char respuesta;
	int tarjeta_ID;
	tarjeta * T;
	cartera mi_cartera(10000);

	cout << "El articulo cuesta " << precio << endl;
	cout << "Paga con tarjeta? S/N" << endl;
	cin >> respuesta;

	if(respuesta=='N'||respuesta=='n')
	{
		pago_dinero p1(mi_cartera);

		if(p1.problema!=NULL)
		{
			cout << p1.problema << endl;
			return;
		}

		cout << "Pago realizado en metalico" << endl;
		return;
	}
	else if(respuesta=='S'||respuesta=='s')
	{
		cout << "Su numero de tarjeta por favor? " << endl;
		cin >> tarjeta_ID;

		//  Tambien puedes practicar con algo automatico como:
		// tarjeta_ID = mi_cartera.tarjeta.ID;
		// Dado que una persona sabe sacar la tarjeta y mirar el numero..
		// La imaginacion es el limite.

		T = ObtenerTarjeta(tarjeta_ID);

		pago_tarjeta p2(precio,T);

		if(p2.problema!=NULL)
		{
			cout << p2.problema << endl;
			return;
		}

		cout << "Pago realizado con la tarjeta " << *T << endl;
	}
	else
	{
		cout << "No le he entendido" << endl;
	}
}
Suponiendo que tenemos una clase tarjeta creada y funcional al igual que una cartera... (Es tan solo un ejemplo aplicado, para que veas como se puede programar) En ese caso también sería bueno añadir el control de saldo y demás en la propia clase.

Date cuenta de que lanzo el pago, y la clase lo comprueba todo. En cualquier caso, la clase derivada debe rellenar un supuesto campo "problema" que es un puntero a una cadena si hay algún problema, y si no dejarlo en NULL. Este campo debe estar en la clase base, porque es común a cualquier pago, no así el problema que pueda surgir (tarjeta no valida, dinero insuficiente...) etc.


Para hacer:

Código:
cout << "Pago realizado con la tarjeta " << *T << endl;
debes sobrecargar el operador << de la clase ostream como friend... Es para mostrarte el mundo infinito que tiene C++ ;) (PD: "Los operadores sobrecargados no sirven para nada" by Blackwind)

Última edición por MaxExtreme; 17/04/2005 a las 13:03
  #9 (permalink)  
Antiguo 17/04/2005, 15:53
 
Fecha de Ingreso: junio-2004
Mensajes: 283
Antigüedad: 20 años, 5 meses
Puntos: 0
wow! muchas gracias por la explicacion! superdetallada, nunca me lo habrian explicado mejor! :D

pero el tema es que me da error al compilar la clase pago.h con lo que me habias indicado. con lo de la inicializacion que me has comentado, nose, me extraña

el error es este

Código:
pagament.h:10: error: expected `{' al final de la entrada
__________________
pOrtfOliO

Última edición por custo; 17/04/2005 a las 16:06
  #10 (permalink)  
Antiguo 17/04/2005, 16:24
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años, 7 meses
Puntos: 17
Copia la línea y te respondo mañana.
  #11 (permalink)  
Antiguo 17/04/2005, 17:39
 
Fecha de Ingreso: junio-2004
Mensajes: 283
Antigüedad: 20 años, 5 meses
Puntos: 0
ya lo tengo, era porque tiene que acabar la línea en {}

Esto es un no acabar, ahora me compila bien, pero me salta un error, este:

Código:
En la función `pagoefectivo::pagoefectivo(float)':
/root/Desktop/segon_apartat/pagoefectivo.cpp:4: undefined reference to `vtable for pagoefectivo'
He leido por ahi que puede ser problema del compilador, pero he probado de solucionarlo y no hay manera.

: ( eso cada vez peor.

Bueno gracias! te estas portando muy bien! ;)
__________________
pOrtfOliO
  #12 (permalink)  
Antiguo 17/04/2005, 19:22
 
Fecha de Ingreso: junio-2004
Mensajes: 283
Antigüedad: 20 años, 5 meses
Puntos: 0
ya está amigo, ya he terminado del todo! muchas muchas gracias por todo, de verdad

1 saludo y hasta otra ;)
__________________
pOrtfOliO
  #13 (permalink)  
Antiguo 18/04/2005, 06:08
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años, 7 meses
Puntos: 17
Nada, a seguir bien ;)

Última edición por MaxExtreme; 18/04/2005 a las 12:27
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 23:18.