Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Cómo implementar el siguiente código en una clase (https://www.clubdelphi.com/foros/showthread.php?t=86213)

eennzzoo 01-07-2014 14:42:51

Cómo implementar el siguiente código en una clase
 
Hola, tengo este codigo [agrega datos de clientes a un archivo] y quisiera implementarle una clase para este codigo.

Código:

void __fastcall TAgregarCliente::menuNuevoClick(TObject *Sender)
{
        editNombre->Text="";
        editApellido->Text="";
        editDni->Text="";
}
void __fastcall TAgregarCliente::btnGuardarClick(TObject *Sender)
{
      TS1->LoadFromFile("datos.txt");
      if ((editNombre->Text != "")&&(editApellido->Text != "")&&(editDni->Text != "")){
                for(int i=0; i<TS1->Count; i=i+3) {
                        if (TS1->Strings[i]==editDni->Text) {
                                editNombre->Text = "";
                                editApellido->Text = "";
                                editDni->Text="";
                                Application->MessageBox(L"El cliente ya es socio.",L"AVISO", MB_OK | MB_ICONEXCLAMATION);
                                break;
                        }else if (i==(TS1->Count-3)){
                                        FILE *F1;
                                        char Nombre[30], Apellido[30], Dni[10];
                                        strcpy(Nombre, AnsiString(editNombre->Text).c_str());
                                        strcpy(Apellido, AnsiString(editApellido->Text).c_str());
                                        strcpy(Dni, AnsiString(editDni->Text).c_str());
                                        F1 = fopen("datos.txt", "a");
                                        if( FS1 == NULL ){
                                                ShowMessage("El archivo no se pudo guardar");
                                                return;
                                        }
                                        fprintf(F1, "%s\n", Dni);
                                        fprintf(F1, "%s\n", Nombre);
                                        fprintf(F1, "%s\n", Apellido);
                                        fclose(F1);
                                        editNombre->Text = "";
                                        editApellido->Text = "";
                                        editDni->Text = "";
                                        Application->MessageBox(L"Has agregado un nuevo cliente.",L"Nuevo cliente", MB_OK);
                                        }
                                }
          }else {
                          Application->MessageBox(L"Completar todos los campos.",L"AVISO", MB_OK | MB_ICONEXCLAMATION);
                }
}

Gracias.

aguml 03-07-2014 13:54:12

¿Y que problema tienes? Crea el .h y declara la clase con sus metodos publicos y demas.

eennzzoo 03-07-2014 14:26:06

Cita:

Empezado por aguml (Mensaje 478612)
¿Y que problema tienes? Crea el .h y declara la clase con sus metodos publicos y demas.

Si ya se, pero no se me ocurre cuales podrian ser sus atributos y metodos. Para que luego la pueda usar dentro de ese codigo.

dec 03-07-2014 15:01:23

Hola,

Me temo que el código en cuestión encierra muchas "cosas" que no son fáciles de dilucidar. Ahí se ven variables, objetos, etc., que no se sabe muy bien de dónde salen, y, así, es casi imposible ayudarte. Tal vez deberías plantear la cuestión de otra forma. Indicando, por ejemplo, qué es lo que se supone que quieres hacer y porqué crees que ello ha de estar en una clase aparte. Por otro lado, recuerda que en el foro se trata de ayudar a resolver problemas más concretos: no se trata de traducir código de un lenguaje a otro, ni de que se desarrollen clases enteras en base a cierto código, etc. Así que deberías concretar bastante más, en mi opinión.

P.D. No escribas en "negrita", puesto que lo que tengas que decir se lee peor, al contrario de lo que pudiera parecer.

eennzzoo 03-07-2014 15:10:11

Cita:

Empezado por dec (Mensaje 478618)
Hola,

Me temo que el código en cuestión encierra muchas "cosas" que no son fáciles de dilucidar. Ahí se ven variables, objetos, etc., que no se sabe muy bien de dónde salen, y, así, es casi imposible ayudarte. Tal vez deberías plantear la cuestión de otra forma. Indicando, por ejemplo, qué es lo que se supone que quieres hacer y porqué crees que ello ha de estar en una clase aparte. Por otro lado, recuerda que en el foro se trata de ayudar a resolver problemas más concretos: no se trata de traducir código de un lenguaje a otro, ni de que se desarrollen clases enteras en base a cierto código, etc. Así que deberías concretar bastante más, en mi opinión.

P.D. No escribas en "negrita", puesto que lo que tengas que decir se lee peor, al contrario de lo que pudiera parecer.

Lo que me piden que use clases y solo tengo ese form que agrega clientes a un archivo. No pido traducir el código a otro lenguaje. Solo pido una idea de como podría implementar una clase para ese programa por así decirlo.

dec 03-07-2014 16:09:39

Hola,

En cualquier caso pides demasiado, en el sentido de que no concretas nada. Por otro lado, y, como te he dicho arriba, el código que has mostrado es difícilmente convertible en una clase: así podrías decírselo a quien te lo haya pedido si lo ha hecho tal cual. Tal vez, insisto, como ya he dicho arriba, podrías decir qué es lo que quieres conseguir, cuál debe ser la funcionalidad de la clase en cuestión. Ahí ya estarías pidiendo que te escribieran dicha clase... pero igual alguien tiene tiempo y ganas suficientes o al menos podría darte alguna orientación sobre cómo hacerlo tú mismo.

Edito: Bueno; mirando de nuevo el código ya se me ocurre alguna cosa... pero yo no domino C++ como para hacer lo que tengo en la cabeza. Tal vez algún otro compañero pueda ayudarte, pues.

dec 03-07-2014 16:36:16

Hola,

No es exactamente lo mismo, porque, por lo demás debe haber muchísimas maneras de hacer lo mismo o algo parecido. Por otro lado, el siguiente código no es C++ (sino Delphi), pero, en fin, por si pudiera servirte de algo, aquí tienes:

Código Delphi [-]
unit UContactos;

interface

uses
  Classes, SysUtils;

type
  EContactoInvalido = Exception;

type
  TContacto = record
    DNI: string;
    Nombre: string;
    Apellidos: string;
  end;

type
  TContactos = class(TObject)
  private
    FRutaBaseDatos: string;
    FContenidoBaseDatos: TStrings;
  private
    function ExisteContacto(const datosContacto: TContacto): Boolean;
  public
    constructor Create(const rutaBaseDatos: string = '');
  public
    procedure GuardarContactos();
    function InsertarContacto(const datosContacto: TContacto): Integer;
  end;

implementation

const
  RUTA_POR_DEFECTO_BASE_DATOS = 'Contactos.txt';

resourcestring
  rsDatosContactoInvalidos = 'Datos del contacto inválidos.';

{ TContactos }

constructor TContactos.Create(const rutaBaseDatos: string = '');
begin
  FRutaBaseDatos := rutaBaseDatos;
  FContenidoBaseDatos := TStringList.Create();

  if Trim(FRutaBaseDatos) = EmptyStr then
    FRutaBaseDatos := ExtractFilePath(ParamStr(0))+RUTA_POR_DEFECTO_BASE_DATOS;

  if FileExists(rutaBaseDatos) then
    FContenidoBaseDatos.LoadFromFile(FRutaBaseDatos);
end;

function TContactos.InsertarContacto(const datosContacto: TContacto): Integer;
begin
  Result := -1;
  if (Trim(datosContacto.DNI) = EmptyStr)
   or (Trim(datosContacto.Nombre) = EmptyStr)
    or (Trim(datosContacto.Apellidos) = EmptyStr) then
  begin
    raise EContactoInvalido.Create(rsDatosContactoInvalidos);
  end;
  if not Self.ExisteContacto(datosContacto) then
  begin
    Result := FContenidoBaseDatos.Add(Format
    (
      '%s|%s|%s',
      [datosContacto.DNI, datosContacto.Nombre, datosContacto.Apellidos]
    ));
  end;
end;

procedure TContactos.GuardarContactos();
begin
  if Trim(FRutaBaseDatos) = EmptyStr then
    FRutaBaseDatos := ExtractFilePath(ParamStr(0))+RUTA_POR_DEFECTO_BASE_DATOS;
  FContenidoBaseDatos.SaveToFile(FRutaBaseDatos);
end;

function TContactos.ExisteContacto(const datosContacto: TContacto): boolean;
begin
  Result := FContenidoBaseDatos.IndexOf(datosContacto.DNI) = -1;
end;

end.

eennzzoo 03-07-2014 16:40:47

Cita:

Empezado por dec (Mensaje 478623)
Hola,

No es exactamente lo mismo, porque, por lo demás debe haber muchísimas maneras de hacer lo mismo o algo parecido. Por otro lado, el siguiente código no es C++ (sino Delphi), pero, en fin, por si pudiera servirte de algo, aquí tienes:

Código Delphi [-]
unit UContactos;

interface

uses
  Classes, SysUtils;

type
  EContactoInvalido = Exception;

type
  TContacto = record
    DNI: string;
    Nombre: string;
    Apellidos: string;
  end;

type
  TContactos = class(TObject)
  private
    FRutaBaseDatos: string;
    FContenidoBaseDatos: TStrings;
  private
    function ExisteContacto(const datosContacto: TContacto): Boolean;
  public
    constructor Create(const rutaBaseDatos: string = '');
  public
    procedure GuardarContactos();
    function InsertarContacto(const datosContacto: TContacto): Integer;
  end;

implementation

const
  RUTA_POR_DEFECTO_BASE_DATOS = 'Contactos.txt';

resourcestring
  rsDatosContactoInvalidos = 'Datos del contacto inválidos.';

{ TContactos }

constructor TContactos.Create(const rutaBaseDatos: string = '');
begin
  FRutaBaseDatos := rutaBaseDatos;
  FContenidoBaseDatos := TStringList.Create();

  if Trim(FRutaBaseDatos) = EmptyStr then
    FRutaBaseDatos := ExtractFilePath(ParamStr(0))+RUTA_POR_DEFECTO_BASE_DATOS;

  if FileExists(rutaBaseDatos) then
    FContenidoBaseDatos.LoadFromFile(FRutaBaseDatos);
end;

function TContactos.InsertarContacto(const datosContacto: TContacto): Integer;
begin
  Result := -1;
  if (Trim(datosContacto.DNI) = EmptyStr)
   or (Trim(datosContacto.Nombre) = EmptyStr)
    or (Trim(datosContacto.Apellidos) = EmptyStr) then
  begin
    raise EContactoInvalido.Create(rsDatosContactoInvalidos);
  end;
  if not Self.ExisteContacto(datosContacto) then
  begin
    Result := FContenidoBaseDatos.Add(Format
    (
      '%s|%s|%s',
      [datosContacto.DNI, datosContacto.Nombre, datosContacto.Apellidos]
    ));
  end;
end;

procedure TContactos.GuardarContactos();
begin
  if Trim(FRutaBaseDatos) = EmptyStr then
    FRutaBaseDatos := ExtractFilePath(ParamStr(0))+RUTA_POR_DEFECTO_BASE_DATOS;
  FContenidoBaseDatos.SaveToFile(FRutaBaseDatos);
end;

function TContactos.ExisteContacto(const datosContacto: TContacto): boolean;
begin
  Result := FContenidoBaseDatos.IndexOf(datosContacto.DNI) = -1;
end;

end.

Ok gracias.

ecfisa 03-07-2014 17:54:22

Hola eennzzoo.

Yo también había pensado en una opción similar a la publicada por dec.

.h:
Código:

#ifndef Unit2H
#define Unit2H

#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>

class Cliente {

private:
  String FNombre;
  String FApellido;
  String FDni;
  String FFileName;
  TStrings *FTS;

public:
  Cliente();
  __property String Nombre  = { read = FNombre, write = FNombre };
  __property String Apellido = { read = FApellido, write = FApellido };
  __property String Dni      = { read = FDni, write = FDni };
  __property String FileName = { read = FFileName, write = FFileName };
  bool Open();
  bool GetData(const String Dni);
  bool Delete(const String Dni);
  bool Save();
  ~Cliente();
};

#endif

.cpp
Código:

#pragma hdrstop
#include "Unit2.h"
#pragma package(smart_init)

Cliente::Cliente()
{
  FTS = new TStringList;
}

bool Cliente::Open()
{
  FTS->LoadFromFile(FFileName);
  return FileExists(FFileName);
}

bool Cliente::GetData(const String Dni)
{
  int p = FTS->IndexOf(Dni);
  if (p != -1) {
    FNombre  = FTS->Strings[p-2];
    FApellido = FTS->Strings[p-1];
    FDni      = FTS->Strings[p];
    return true;
  } else {
    MessageBox(0,"Cliente no encontrado", "", MB_ICONERROR);
    return false;
  }
}

bool Cliente::Delete(const String Dni)
{
  int p = FTS->IndexOf(Dni);
  bool r = false;
  if (p == -1)
    MessageBox(0,"Cliente no encontrado", "", MB_ICONERROR);
  else if (MessageBox(0, "¿ Borra el cliente ?","",MB_YESNO+MB_ICONQUESTION)==IDYES) {
    FTS->Delete(p);
    r = true;
  }
  return r;
}

bool Cliente::Save()
{
  if (FNombre.IsEmpty() || FApellido.IsEmpty() || FDni.IsEmpty()) {
    MessageBox(0,"Faltan uno o mas datos requeridos", "", MB_ICONERROR);
    return false;
  } else if (FTS->IndexOf(FDni)!= -1) {
    MessageBox(0,"Cliente existente", "", MB_ICONERROR);
    return false;
  } else {
    FTS->Add(FNombre);
    FTS->Add(FApellido);
    FTS->Add(FDni);
    FTS->SaveToFile(FFileName);
    return true;
  }
};

Cliente::~Cliente()
{
  delete FTS;
}

Ejemplo de uso:
Código:

...
#include "Unit2.h"
...

Cliente *cl;

void __fastcall TForm1::FormCreate(TObject *Sender)
{
 cl = new Cliente();
 cl->FileName = "cliente.txt";  /* ruta+nombre de archivo */
 cl->Open();
}

void __fastcall TForm1::btnShowClick(TObject *Sender)
{
  if (cl->GetData(Edit1->Text)) {
    edNom->Text = cl->Nombre;
    edApe->Text = cl->Apellido;
    edDni->Text = cl->Dni;
  }
}

void __fastcall TForm1::btnDeleteClick(TObject *Sender)
{
  if (cl->Delete(Edit1->Text)) {
    edNom->Clear();
    edApe->Clear();
    edDni->Clear();
  }
}

void __fastcall TForm1::btnSaveClick(TObject *Sender)
{
  cl->Save();
}
...

Espero que de las dos sugerencias puedas sacar ideas para implementar tu clase.

Saludos :)

eennzzoo 03-07-2014 17:59:23

Cita:

Empezado por ecfisa (Mensaje 478634)
Hola eennzzoo.

Yo también había pensado en una opción similar a la publicada por dec.

.h:
Código:

#ifndef Unit2H
#define Unit2H

#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>

class Cliente {

private:
  String FNombre;
  String FApellido;
  String FDni;
  String FFileName;
  TStrings *FTS;

public:
  Cliente();
  __property String Nombre  = { read = FNombre, write = FNombre };
  __property String Apellido = { read = FApellido, write = FApellido };
  __property String Dni      = { read = FDni, write = FDni };
  __property String FileName = { read = FFileName, write = FFileName };
  bool Open();
  bool GetData(const String Dni);
  bool Delete(const String Dni);
  bool Save();
  ~Cliente();
};

#endif

.cpp
Código:

#pragma hdrstop
#include "Unit2.h"
#pragma package(smart_init)

Cliente::Cliente()
{
  FTS = new TStringList;
}

bool Cliente::Open()
{
  FTS->LoadFromFile(FFileName);
  return FileExists(FFileName);
}

bool Cliente::GetData(const String Dni)
{
  int p = FTS->IndexOf(Dni);
  if (p != -1) {
    FNombre  = FTS->Strings[p-2];
    FApellido = FTS->Strings[p-1];
    FDni      = FTS->Strings[p];
    return true;
  } else {
    MessageBox(0,"Cliente no encontrado", "", MB_ICONERROR);
    return false;
  }
}

bool Cliente::Delete(const String Dni)
{
  int p = FTS->IndexOf(Dni);
  bool r = false;
  if (p == -1)
    MessageBox(0,"Cliente no encontrado", "", MB_ICONERROR);
  else if (MessageBox(0, "¿ Borra el cliente ?","",MB_YESNO+MB_ICONQUESTION)==IDYES) {
    FTS->Delete(p);
    r = true;
  }
  return r;
}

bool Cliente::Save()
{
  if (FNombre.IsEmpty() || FApellido.IsEmpty() || FDni.IsEmpty()) {
    MessageBox(0,"Faltan uno o mas datos requeridos", "", MB_ICONERROR);
    return false;
  } else if (FTS->IndexOf(FDni)!= -1) {
    MessageBox(0,"Cliente existente", "", MB_ICONERROR);
    return false;
  } else {
    FTS->Add(FNombre);
    FTS->Add(FApellido);
    FTS->Add(FDni);
    FTS->SaveToFile(FFileName);
    return true;
  }
};

Cliente::~Cliente()
{
  delete FTS;
}

Ejemplo de uso:
Código:

...
#include "Unit2.h"
...

Cliente *cl;

void __fastcall TForm1::FormCreate(TObject *Sender)
{
 cl = new Cliente();
 cl->FileName = "cliente.txt";  /* ruta+nombre de archivo */
 cl->Open();
}

void __fastcall TForm1::btnShowClick(TObject *Sender)
{
  if (cl->GetData(Edit1->Text)) {
    edNom->Text = cl->Nombre;
    edApe->Text = cl->Apellido;
    edDni->Text = cl->Dni;
  }
}

void __fastcall TForm1::btnDeleteClick(TObject *Sender)
{
  if (cl->Delete(Edit1->Text)) {
    edNom->Clear();
    edApe->Clear();
    edDni->Clear();
  }
}

void __fastcall TForm1::btnSaveClick(TObject *Sender)
{
  cl->Save();
}
...

Espero que de las dos sugerencias puedas sacar ideas para implementar tu clase.

Saludos :)

Si ahora si, gracias.

dec 03-07-2014 19:23:13

Hola,

Conste que mi clase de más arriba contiene un error: no destruyo la instancia de "FContenidoBaseDatos". No me he dado cuenta antes.

aguml 03-07-2014 20:21:59

ecfisa ¿Que es eso de __property? Suena mas a un componente.

ecfisa 03-07-2014 21:10:35

Hola aguml.

Básicamente una propiedad, es una extensión creada para C++ Builder que permite unificar métodos de acceso y modificación a miembros de una clase. Su uso no es privativo de los componentes.

Cabe aclarar que C++ estandar no incluye el concepto de propiedad y que C++ Builder recibe de la VCL, si tratásemos con ANSI C++ tendríamos que escribir:
Código:

class MiClass {
private:
  int FValue;
public:
  void SetValue(int Value) { FValue = Value; }
  int GetValue() { return FValue; }
};

Saludos :)


La franja horaria es GMT +2. Ahora son las 04:50:00.

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