Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 25-11-2009
NEG1414 NEG1414 is offline
Miembro
 
Registrado: mar 2007
Posts: 177
Poder: 18
NEG1414 Va por buen camino
Pasar Registro por Referencia

Buenas:

Quisiera saber como paso un registro por referencia

En principio tengo una Clase1 donde creo un tipo dato Registro
Código:
  class Clase1    
  {
     Public:
        struct Registro
           {
                bool Esta;
                bool Dentro;                
                bool Frio;
           }
 
          typedef Registro TRegistro[15];
          TRegistro  Reg;     
  }

   ModificarRegistro( TRegistro &Reg);


Tengo Otra Clase2 donde declaro una Variable tipo Reg la cual mando al procedimiento ModificarRegistro de la Clase1 para obtener nuevos datos.

Código:
 
include "Clase1.h"

 class Clase2    
 {
     Public:    

         Clase1::TRegistro  *Registros;
 }

  CambiarValores Reg()        
   {
       //iNICIALIZAR                      
      for(int i=1;i<15;i++)     
        {         
           (*Registros)[i].Esta   =false;         
           (*Registros)[i].Dentro=false;
           (*Registros)[i].Frio     =false;
         }
  
       //Calcular Valores
       ModificarRegistro(Registros);
 }
Por supuesto no funciona,que hago mal Gracias.
Responder Con Cita
  #2  
Antiguo 25-11-2009
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Tienes mal planteadas tus clases. Imagino que parte son errores tipográficos.

Te pongo un ejemplo:

Código:
class Clase1
  {
     public:
        struct Registro
           {
                bool Esta;
                bool Dentro;                
                bool Frio;
           };
 
          typedef Registro TRegistro[15];
          TRegistro  Reg;     
  };

   ModificarRegistro( Clase1::TRegistro &Reg);

class Clase2
 {
     public:

         Clase1::TRegistro  Registros; // no declares un puntero sino un objeto.
         CambiarValores();
 };

Clase2::CambiarValores()
   {
       //iNICIALIZAR                      
      for(int i=0;i<15;i++)
        {
           Registros[i].Esta   =false;
           Registros[i].Dentro =false;
           Registros[i].Frio   =false;
         }

       //Calcular Valores
 }

ModificarRegistro( Clase1::TRegistro &Reg)
{
      for(int i=0;i<15;i++)
        {
           Reg[i].Esta   =true;
           Reg[i].Dentro =true;
           Reg[i].Frio   =true;
         }
}
Código:
    Clase2 C2;
    C2.CambiarValores();
    ModificarRegistro(C2.Registros);
Responder Con Cita
  #3  
Antiguo 26-11-2009
NEG1414 NEG1414 is offline
Miembro
 
Registrado: mar 2007
Posts: 177
Poder: 18
NEG1414 Va por buen camino
Gracias por contestar, funciona perfectamente.... pero he rizado el rizo y me encuentro en un atolladero...El caso es que la variable Registro la quiero pasar por referencia como parametro en el constructor de la clase,
me explico.

Para no crear conflictos he creado una clase comodin en la que declaro la variable registros

Código:
 Class TComodin
 {
    public
 
      struct Registro
      { 
          bool esta;
          bool Dentro;
          bool Frio;
      }

     typedef Registro  TRegistros[15];

 }

He creado una Clase1 cuyo constructor tendra como parametro una variable pasada por referncia (Registro)
y una Clase2 que la LLama.

Código:
 include "Comodin.h"

Class  TClase1
{

  public:

   _fastcall  TClase1(TComponent* Owner,TComodin:TRegistros &Regs)    

}



 include "Comodin.h"
 include "Clase1.h"

Class  TClase2
{

  public:

  TClase1 *Clas1;
  TComodin::TRegistros  Reg; 
}


Cuando llamo a la clase de la forma

Código:
Clas1 = new TClase1(this,Reg);

Me da el error : Could Not Find a mach for TClase1::TCLase1(TClase2* Const, TComodin::Reg*)


¿Se puede hacer,No tiene Sentido.....? Gracias
Responder Con Cita
  #4  
Antiguo 26-11-2009
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
El problema está en que typedef realmente no crea nuevos tipos sino que es mas bien un alias. De esta forma como TRegistro[15] es realmente el tipo básico Registro*, el compilador no entiende cuando se trata de un miembro de una clase.

Puedes usar un truco utilizando una referencia intermedia:
Código:
class TComodin
{
   public:

      struct Registro
      {
          bool esta;
          bool Dentro;
          bool Frio;
      };

      typedef Registro  TRegistro[15];
};

class  TClase1
{

  public:

  TClase1(TComodin::TRegistro& R);

};

TClase1::TClase1(TComodin::TRegistro&)
{
}

class  TClase2
{
  public:

  TComodin::TRegistro  Reg;
  TClase1 *Clas1;

  void Funcion();
};

void TClase2::Funcion()
{
  TClase2 C2;
 
  // Declaro yna referencia del tipo TComodin::TRegistro a C2.Reg
  // Esa referencia no es realmente una variable...
  TComodin::TRegistro &Reg = C2.Reg;
  Clas1 = new TClas1(Reg);

  // Sin embargo esto funciona talcual, sin necesidad de ninguna referencia:
  TComodin::TRegistro R;
  Clas1 = new TClas1(R);
}
Saludos.

Última edición por escafandra fecha: 26-11-2009 a las 13:16:37.
Responder Con Cita
  #5  
Antiguo 26-11-2009
NEG1414 NEG1414 is offline
Miembro
 
Registrado: mar 2007
Posts: 177
Poder: 18
NEG1414 Va por buen camino
Buenas

He intentado utilizar tu codigo pero me da un error....valla por delante que TClase2 y TCLase1 en mi programa son Form con lo cual uno de los constructores
es
Código:
   _fastcall TClase2(TComponent *Owner);
El error me lo da en

Código:
        TClase2 C2;
y es : Style classes must be constructed using operator new;

he probado con

Código:
  TClase C2 = new TClase2(this);
Y me da el mismo error


Gracias
Responder Con Cita
  #6  
Antiguo 26-11-2009
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
En C++ existen dos formas de crear un objeto:

1- Una es crearlo directamente declarándolo como cualquier variable. Si queremos pasarle parámetros ponemos parénteis y entonces lo que hacemos es llamar a un constructor distinto al constructor por defecto que no tiene parámetros.

2- La otra es declarar un puntero del tipo de la clase que queremos y cuando interese crearlo con un operador new y el constructor.

Podemos tener varios constructores.

Cuando usamos las VCL, por su construcción, no podemos declarar objetos directamente, sólo punteros, por lo que en tu caso sólo funcionará esto:
Código:
TClase* C2 = new TClase2(this);
si creas un nuevo constructor, y en general para cualquier clase derivada, lo debes hacer así:

Código:
class TClase: public TForm
{
.......
   public:
   // Constructores:
      __fastcall TClase(TComponent* Owner); // por defecto en la VCL
      __fastcall TClase(TComponent* Owner, TComodin::TRegistro&); // Otro...
.......

};

// Fíjate que tienes que llamar al constructor de la clase madre, en este caso TForm. Se hace con esta sintaxis:
__fastcall TClase::TClase(TComponent* Owner, TComodin::TRegistro& Reg): TForm(Owner) 
// aquí, seguido de comas podemos seguir llamando a constructores si tiene herencia múltiple
// o declarando variables o miembros: Variable1(valor1), Variable2(valor2)
{
    //codigo
}
Espero haberte aclarado algo.

Saludos.
Responder Con Cita
  #7  
Antiguo 26-11-2009
NEG1414 NEG1414 is offline
Miembro
 
Registrado: mar 2007
Posts: 177
Poder: 18
NEG1414 Va por buen camino
Gracias por Contestar (y por la clase magistral) he probado mediante

Código:
class TClase2;
{
   public:
  
    TComodin::TRegistro  Reg;
    void Inicializar();  
    void Funcion();   
}


void TClase2::Inicializar()
{
   Reg.Esta= true;
   Reg.Dentro = false;
   Reg.Frio    = true;
}

void TClase2::Funcion()
{
 
   TClase2* C2 = new TClase2(this);
   TComodin::TRegistro &Reg = C2.Reg;

   P = new TClase1(this,Reg);

   delete C2;
   delete P;
}
funciona pasa la variable Reg por referencia al Constructor de Clase1,modifico el valor en Clase1 y regresa a Clase2 modificada......pero hay un problema:
Yo declaro la Variable Reg en Clase2 como Global, la inicializo con una serie de valores pero una vez en FUNCION(); al ejecutar TClase2 *C2 =new TClase1(this) pierde eses valores y envia otros.
Ademas al salir de la funcion en la que llamo a clase1 (FUNCION()) la variable pierde los valores Modificados.

Es como si la variable Reg que paso como parametro del Constructor Clase1 fuera Local de Funcion().

He pensado Crear otra Variable Global del mismo tipo que Reg, y Asignarle los valores ya modificados de Reg,dentro de Funcion();pero en mi programa debere hacer esto mismo con varias variables que funcionaran igual que Reg (varios constructores de Clase1) y me parece algo egorroso...Hay otra solucion, Gracias otra Vez.
Responder Con Cita
  #8  
Antiguo 26-11-2009
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Cita:
Empezado por NEG1414 Ver Mensaje
hay un problema:
Yo declaro la Variable Reg en Clase2 como Global, la inicializo con una serie de valores pero una vez en FUNCION(); al ejecutar TClase2 *C2 =new TClase1(this) pierde eses valores y envia otros.
Ademas al salir de la funcion en la que llamo a clase1 (FUNCION()) la variable pierde los valores Modificados.

Es como si la variable Reg que paso como parametro del Constructor Clase1 fuera Local de Funcion().
Bueno, creo que estás algo liado y que no terminas de comprender alguna de las cosas de la POO.

En una clase no existen variables globales. Sólo son miembros públicos, protegidos o privados. Los públicos pueden ser accedidos por elementos externos de la clase a través de un objeto, pero serán siempre locales a ese objeto, es decir cada vez que crees una nueva instancia, sus valores no tienen porqué ser iguales. Los privados no podrán accederse nada mas que desde la misma clase y los protegidos se comportan como públicos para objetos de esa clase pero si de ella se deriva otra, se heredan como privados.

Existe un tipo especial de miembro que se declara como static, este tipo implica que sólo existirá una copia del mismo por lo que será común a todos los objetos creados de esa clase, es algo mas parecido a una variable global... y se accede a través del nombre de la clase y no desde un objeto. Existe aunque no existan objetos de esa clase. Como ves el sistema de encapsulamiento de datos de la POO del C++ es férreo y potente.

Por este motivo, si declaras dos objetos de una clase, sus datos miembros, en este caso, Reg (del tipo TRegistro) serán diferentes, a no ser que los declares static.

Ahora debes pensar en qué es lo que quieres hacer o conseguir y luego diseñar tus clases como mejor se ajusten a tus necesidades de desarrollo.

Espero no haberte confundido con mis pobres explicaciones.

Saludos.
Responder Con Cita
  #9  
Antiguo 27-11-2009
NEG1414 NEG1414 is offline
Miembro
 
Registrado: mar 2007
Posts: 177
Poder: 18
NEG1414 Va por buen camino
Gracias por tu explicacion
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
pasar un registro de un dbedit a otro con el procedure edit betty_loo Conexión con bases de datos 1 07-11-2007 22:51:55
Referencia circular Enan0 Varios 3 31-10-2006 22:56:26
referencia circular melon OOP 1 16-04-2006 02:13:00
variables por referencia shaktale Varios 2 11-06-2003 12:24:59


La franja horaria es GMT +2. Ahora son las 20:19:21.


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
Copyright 1996-2007 Club Delphi