Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   problemas al crear objetos en delphi (https://www.clubdelphi.com/foros/showthread.php?t=68206)

rodrigo881215 31-05-2010 21:54:43

problemas al crear objetos en delphi
 
Hola que tal, soy nuevo en esto de programar con delphi y me dejaron un proyecto de de cajero automatico. El trabajo consiste en pasar un cajero hecho en builder a delphi, el problema es que me marca errores en tiempo de ejecucion, marca un Access Violation, pienso que el problema puede ser que no estoy creando bien los objetos de mi clases o que no estan bien declarados, tambien en builder uso la clase vector para almacenar datos no se si alla una parecida en delphi, la que encontre es TList, pero haber si me recomienda otra. Aqui les anexo parte del codigo que creo que es el problema. Espera me puedan ayudar y me respondan pronto. Gracias.

Código Delphi [-]
unit UBaseDatosBanco;

interface

uses
   Classes, UCuenta, Forms;

type
   //cuentas = TList;
   BaseDatosBanco = class (TObject)
   public
      constructor Create;
      function autenticarUsuario(numeroCuentaUsuario, nipUsuario: Integer): Boolean;
      function obtenerSaldoDisponible(numeroCuentaUsuario: Integer): Double;
      function obtenerSaldoTotal(numeroCuentaUsuario: Integer): Double;
      procedure abonar(numeroCuentaUsuario: Integer; monto: Double);
      procedure cargar(numeroCuentaUsuario: Integer; monto: Double);
   private
      //cuentas: TList;
      function obtenerCuenta(numeroCuenta: Integer): Cuenta;
   end;

var
   cuentas: TList;
   cuentaUsuarioPtr: Cuenta;
   cuenta1, cuenta2, cuenta3: Cuenta;

implementation

constructor BaseDatosBanco.Create;
begin
   //inherited Create;
   cuentas := TList.Create;
   cuenta1 := Cuenta.Create(12345, 54321, 1000.0, 1200.0);
   cuenta2 := Cuenta.Create(98765, 56789, 200.0, 200.0);
   cuenta3 := Cuenta.Create(69, 96, 1800.0, 2000.0);
   cuentas.Add(cuenta1);
   cuentas.Add(cuenta2);
   cuentas.Add(cuenta3);
end;

function BaseDatosBanco.obtenerCuenta(numeroCuenta: Integer): Cuenta;
var
   i: Integer;
begin
   for i := 0 to 2 do
   begin
      if ((Cuenta(cuentas.Items[i]).obtenerNumeroCuenta) = numeroCuenta) then
         obtenerCuenta := Cuenta(cuentas.Items[i]);
         //Application.MessageBox(Cuenta(cuentas.Items[i]), "", 0);
   end;
   obtenerCuenta := nil;
end;

function BaseDatosBanco.autenticarUsuario(numeroCuentaUsuario, nipUsuario: Integer): Boolean;
{var
 cuentaUsuarioPtr: Cuenta;}
begin
   cuentaUsuarioPtr := obtenerCuenta(numeroCuentaUsuario);
   if (cuentaUsuarioPtr <> nil) then autenticarUsuario := cuentaUsuarioPtr.validarNip(nipUsuario)
   else
      autenticarUsuario := false
end;

function BaseDatosBanco.obtenerSaldoDisponible(numeroCuentaUsuario: Integer): Double;
begin;
   cuentaUsuarioPtr := obtenerCuenta(numeroCuentaUsuario);
   obtenerSaldoDisponible := cuentaUsuarioPtr.obtenerSaldoDisponible;
end;

function BaseDatosBanco.obtenerSaldoTotal(numeroCuentaUsuario: Integer): Double;
begin
   cuentaUsuarioPtr := obtenerCuenta(numeroCuentaUsuario);
   obtenerSaldoTotal := cuentaUsuarioPtr.obtenerSaldoTotal;
end;

procedure BaseDatosBanco.abonar(numeroCuentaUsuario: Integer; monto: Double);
begin
   cuentaUsuarioPtr := obtenerCuenta(numeroCuentaUsuario);
   cuentaUsuarioPtr.abonar(monto);
end;

procedure BaseDatosBanco.cargar(numeroCuentaUsuario: Integer; monto: Double);
begin
   cuentaUsuarioPtr := obtenerCuenta(numeroCuentaUsuario);
   cuentaUsuarioPtr.cargar(monto);
end;

end.

LoPiTaL 31-05-2010 23:42:41

No sé si será el origen de tu error, pero creo que el error está en la función

Código Delphi [-]
function BaseDatosBanco.obtenerCuenta(numeroCuenta: Integer): Cuenta;
var
i: Integer;
begin
for i := 0 to 2 do
begin
if ((Cuenta(cuentas.Items[i]).obtenerNumeroCuenta) = numeroCuenta) then
obtenerCuenta := Cuenta(cuentas.Items[i]);
//Application.MessageBox(Cuenta(cuentas.Items[i]), "", 0);
end;
obtenerCuenta := nil;
end;

ya que aquí no pasa como en C, que cuando asignas el valor de la función, ésta termina. En Delphi, "obtenerCuenta" es una variable más (a mí me gusta sustituirla por "Result", que referencia lo mismo y sirve para todos los nombres de funciones) y no por darle un valor fuerza el fin de la función. Deberías añadir un Exit dentro del if cuando asignas el valor de obtenerCuenta.
No me he fijado en el resto de funciones, pero si haces cosas similares, es posible que también te haya sucedido.

De hecho, si en lugar de hacer "Compile" haces "Build" el compilador te generará un Warning diciéndote que el valor asignado a obtenerCuenta no se utiliza nunca. Es por esto, porque al final es sobreescrito por nil.

Otra cosa, por convenio, todos los objetos, clases, etc en Delphi empiezan con T. Por tanto tu clase deberías renombrarla a TCuenta (sólo es por convenio, no es obligatorio, pero así podrás diferenciar clases de interfaces que empiezan por I y de punteros a clases que empiezan por P).

Espero haberte ayudado,
Un saludo,
LoPiTaL

rodrigo881215 01-06-2010 00:16:34

Gracia por responderme y por la ayuda, pero el error persiste, pienso que puede ser por no se crean bien los objetos, esa clase que puse la llamo desde mi clase principal donde esta el formulario, colo esto en el contructor baseDatosBanco := BaseDatosBanco.Create

De esa manera intento cargar las cuentas en memoria para que esten almacenadas en el TList.

Espero puedan ayudarme

LoPiTaL 01-06-2010 08:52:47

Ok, voy a seguir planteándote cosas, y ya nos vas diciendo... a priori no veo ningún otro error, salvo cosas que veo que no son muy correctas y tal vez te lleven al final al error:

Código Delphi [-]
var
   cuentas: TList;
   cuenta1, cuenta2, cuenta3: Cuenta;

Estas variables deberían estar declaradas dentro de la clase BaseDatosBanco, y no como globales, ya que si creas más de una instancia de BaseDatosBanco se te recrearán y se quedarán sin liberar.
Si las quieres globales NO las debes crear dentro del constructor de la clase, sino deberías crearlas y liberarlas en un bloque initialization / finalization, que se ejecutan al cargar / descargar la unit en cuestión, sin necesidad de crear una instancia de nadie.
Código Delphi [-]
   cuentaUsuarioPtr: Cuenta;

Ésta otra variable debería ser local en cada función, ya que sólo la utilizas como auxiliar...

Cita:

esa clase que puse la llamo desde mi clase principal donde esta el formulario, colo esto en el contructor baseDatosBanco := BaseDatosBanco.Create
No sé hasta qué punto sea correcto (y seguro) llamarle de la misma forma a la variable que a la clase (otra razón más para añadirle la T al principio del nombre de la clase). Recuerda que Delphi no es case sensitive.

Bueno, a priori no se me ocurre nada más. Si alguien tiene alguna sugerencia más sería interesante que la plantease.

Un saludo,
LoPiTaL

Neftali [Germán.Estévez] 01-06-2010 10:49:34

Cita:

Empezado por rodrigo881215 (Mensaje 365782)
Gracia por responderme y por la ayuda, pero el error persiste, pienso que puede ser por no se crean bien los objetos, esa clase que puse la llamo desde mi clase principal donde esta el formulario, colo esto en el contructor baseDatosBanco := BaseDatosBanco.Create

De esa manera intento cargar las cuentas en memoria para que esten almacenadas en el TList.

Normalmente los errores de este tipo suelen ser por problemas con objetos mal creados o mal destruídos como tú dices.
Estaría bien, que ejecutes tu programa paso a paso y nos diferas en qué línea te marca o te salta el error. A partir de ahí podemos seguir investigando.

Si es en los create:
Código Delphi [-]
cuenta1 := Cuenta.Create(12345, 54321, 1000.0, 1200.0);
Habrá que ver cómo es el constructor de la clase.


La franja horaria es GMT +2. Ahora son las 10:42:28.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi