Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Problema con Clase (https://www.clubdelphi.com/foros/showthread.php?t=34088)

pelaorb68 26-07-2006 19:28:02

Problema con Clase
 
Hola a todos, como están. Estoy incursionando con los objetos, pero necesito de vuestra ayuda nuevamente.
Me he creado una clase pequeña, la cual una de sus Propiedades es del tipo record. El punto es que cuando trato de asignar un valor a la Porpiedad de la clase, el compilador me arroja el mensaje "Left side cannot be assigned to".

La clase es como siguie:


Código Delphi [-]
type
  TTipoGrafico = record
    Tipo  : Integer;
    Trazo : byte;
    ColorSerie: TColor;
  end;
 
  TPGSeries = class
  private
    FGrafico       : TTipoGrafico;
    FItem          : Integer;
  public
    property Grafico: TTipoGrafico read FGrafico write FGrafico;
    property Item: Integer read FItem write FItem;
    constructor Create;
  end;




Cuando trato de hacer lo siguiente: <LaClase>.Grafico.Tipo := 1; <--- "Left side cannot ........"

Espero me puedan ayudar, please.....

De ante mano, muchas gracias....

dec 26-07-2006 19:53:32

Hola,

El error que comentas se da cuando tratas de asignar un valor a una variable que únicamente puede leerse, no escribirse. En todo caso, haciendo alguna prueba con el código que has expuesto, y, limitándonos a lo que nos ocupa, no he podido reproducir el error que dices:

Código Delphi [-]
unit Unit1;

interface

uses
  Forms, Classes, Controls, StdCtrls, Graphics;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;


type
  TTipoGrafico = record
    Tipo  : Integer;
    Trazo : byte;
    ColorSerie: TColor;
  end;

  TPGSeries = class
  private
    FGrafico: TTipoGrafico;
    FItem: Integer;
  public
    property Grafico: TTipoGrafico read FGrafico write FGrafico;
    property Item: Integer read FItem write FItem;
    constructor Create;
  end;



var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  SysUtils, Dialogs;

constructor TPGSeries.Create;
begin
  inherited;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  PGSeries: TPGSeries;
begin
  PGSeries := TPGSeries.Create;
  try
    PGSeries.FGrafico.Tipo := 1;

    // Muestra "1"
    ShowMessage( IntToStr ( PGSeries.FGrafico.Tipo ) );

  finally
    PGSeries.Free;
  end;
end;

end.

pelaorb68 26-07-2006 20:17:57

Gracias por tu pronta respuesta Dec.....pero estas asignando la Propiedad FGrafico.Tipo que está definida en la misma unidad. Si cambias FGrafico por Grafico.Tipo te dará el mismo error que me ocurre a mi. Mi clase está definida en una unit aparte, por lo tanto cuando necesito ocuparla la llamo desde las unit que la requieren.

pelaorb68 26-07-2006 21:58:11

Será que el tipo de datos TTipoGrafico debiera ser Class en vez de Record, y definir el Read y Write para cada property (Tipo, Trazo y ColorSerie)..??????? De esa forma sí podré asignarle valor a la propiedad Grafico.Tipo???????

Ejmp:

Código Delphi [-]
  TTipoGrafico = class
  private
    FTipo: Integer;
    FTrazo: Integer;
    FColorSerie: TColor;
  public
    property Tipo: Integer read FTipo write FTipo;
    property Trazo: Integer read FTrazo write FTrazo;
    property ColorSerie: TColor read FColorSerie write FColorSerie;
    constructor Create;
  end;


Agradezco todas las ayudas que me puedan brindar..........

dec 26-07-2006 22:11:42

Hola,

Tienes razón, no he caído en lo que dices. Y de hecho pude hacerlo porque al estar la clase en la misma unidad que en la que la utilizaba, Delphi me ha permitido acceder a "FGrafico", siendo como es una variable privada de la clase. :o

dec 26-07-2006 22:30:50

Hola,

Yendo al tema que nos ocupa, y aunque estoy muy espeso (y no sé si se me entenderá) diré que no parece ser posible asignar la variable del "record" que nos ocupa tal como lo quieres hacer. Claro, mira tú, ¡si fuera posible no estaríamos aquí hablando de ello! Si es que... cuando digo que estoy espeso...

Lo siguiente sí que es posible:

Código Delphi [-]
unit Unit1;

interface

uses
  Forms, Classes, Controls, StdCtrls, Graphics;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;


type
  TTipoGrafico = record
    Tipo  : Integer;
    Trazo : byte;
    ColorSerie: TColor;
  end;

  TPGSeries = class
  private
    FGrafico: TTipoGrafico;
    FItem: Integer;
    procedure SetTipoGrafico(value: TTipoGrafico);
  public
    property Grafico: TTipoGrafico read FGrafico write SetTipoGrafico;
    property Item: Integer read FItem write FItem;
    constructor Create;
  end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  SysUtils, Dialogs;

// TPGSeries

constructor TPGSeries.Create;
begin
  inherited;
end;

procedure TPGSeries.SetTipoGrafico(value: TTipoGrafico);
begin
  FGrafico := value;
end;

// TForm1

procedure TForm1.Button1Click(Sender: TObject);
var
  tg: TTipoGrafico;
  PGSeries: TPGSeries;
begin
  PGSeries := TPGSeries.Create;
  try
    tg.Tipo := 1;
    tg.Trazo := 1;
    tg.ColorSerie := 0;

    // Asignación correcta
    PGSeries.Grafico := tg;

    // Mostrará 0
    ShowMessage( IntToStr ( PGSeries.Grafico.ColorSerie ) );

  finally
    PGSeries.Free;
  end;
end;

end.

Pero, claro, tú lo que quieres dar un valor a un elemento en concreto del "record" "TTipoGrafico", y no tener que dar valor a todas las variables. Está bien.

Entonces esta línea de tu código tiene conlleva una contradicción, causa el problema, o yo estoy equivocado:

Código Delphi [-]
property Grafico: TTipoGrafico read FGrafico write FGrafico;

¿Ahí no se está diciendo, "la propiedad Grafico es de tipo "TTipoGrafico" y para leerla puede accederse a la variable privada "FGrafico", y para escribirla ha de escribirse la variable "FGrafico"...?

Es decir, "para escribirla hay que escribir la variable "FGrafico", de tipo "TTipoGrafico". No sé exactamente porqué, pero, por lo que se ve no puedes acceder a los elementos de la variable "FGrafico" por separado. O eso, o alguien que sepa más nos lo explica. ;)

¿Y entonces? ¿Qué pasa si quieres dar la posibilidad de cambiar el valor de un elemento de la variable "FGrafico"? Pues a mí a bote pronto se me ocurre algo que añado al código que puse anteriormente:

Código Delphi [-]
unit Unit1;

interface

uses
  Forms, Classes, Controls, StdCtrls, Graphics;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;


type
  TTipoGrafico = record
    Tipo  : Integer;
    Trazo : byte;
    ColorSerie: TColor;
  end;

  TPGSeries = class
  private
    FGrafico: TTipoGrafico;
    FItem: Integer;
    procedure SetGrafico(value: TTipoGrafico);
    procedure SetTipoGrafico(value: Integer);
    function GetTipoGrafico: Integer;
  public
    property TipoGrafico: Integer read GetTipoGrafico write SetTipoGrafico;
    property Grafico: TTipoGrafico read FGrafico write SetGrafico;
    property Item: Integer read FItem write FItem;
    constructor Create;
  end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  SysUtils, Dialogs;

// TPGSeries

constructor TPGSeries.Create;
begin
  inherited;
end;

function TPGSeries.GetTipoGrafico: Integer;
begin
  Result := FGrafico.Tipo;
end;

procedure TPGSeries.SetTipoGrafico(value: Integer);
begin
  if FGrafico.Tipo <> value then
    FGrafico.Tipo := value;
end;

procedure TPGSeries.SetGrafico(value: TTipoGrafico);
begin
  FGrafico := value;
end;

// TForm1

procedure TForm1.Button1Click(Sender: TObject);
var
  tg: TTipoGrafico;
  PGSeries: TPGSeries;
begin
  PGSeries := TPGSeries.Create;
  try

    PGSeries.TipoGrafico := 1;

    // Mostrará 1
    ShowMessage( IntToStr ( PGSeries.Grafico.Tipo ) );

  finally
    PGSeries.Free;
  end;
end;

end.

pelaorb68 26-07-2006 23:07:46

Dec, yá solucioné mi problema....Los tipos de datos Record los dejé como Class, en donde cada property tiene su Read y Write. Ahora sí puedo asignar Grafico.Tipo directamente........

Código Delphi [-]
  TTipoGrafico = class
  private
    FTipo: Integer;
    FTrazo: Integer;
    FColorSerie: TColor;
  public
    property Tipo: Integer read FTipo write FTipo;
    property Trazo: Integer read FTrazo write FTrazo;
    property ColorSerie: TColor read FColorSerie write FColorSerie;
  end;

Por lo tanto en el constructor de la clase TPGSeries hago el create de la clase TTipoGrafico.

No sé si la forma en que lo he hecho es lo correcto, pero por el momento soluciona mi problema. Ya tendré más tiempo para aprender la mejor forma de definir y utilizar las Clases y Objetos......

Muchísimas gracias por la ayuda.....

Al González 27-07-2006 04:57:57

¡Hola a todos!

A primera vista se ve extraño este comportamiento del compilador, pero quizá, si lo analizamos con mayor detalle, podríamos encontrar su causa (jusificada o accidental).

En la primera oportunidad haré algunas pruebas de esto.

Un abrazo extraño.

Al González. :)


La franja horaria es GMT +2. Ahora son las 07:08:21.

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