Run time da degisken olusturma

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Kullanıcı avatarı
Opt2000
Üye
Mesajlar: 216
Kayıt: 09 Tem 2003 10:04

Re: Run time da degisken olusturma

Mesaj gönderen Opt2000 »

Selam,

Variant tipleri kullanabilirsin. Genelde yavaş diye tavsiye edilmez, ama programın kodunu kullanıcıya yazdırıyorsan bahsedilen yavaşlık seni pek ilgilendirmez sanırım.

Variant'ı hemen de kullanabilirsin, ama güvenli olsun, kontrolümde olsun ve bir kere bütün veri tiplerini tanımlayım, ondan sonra da işim çok kolay olsun diyorsan aşağıdaki kod işini görecektir.

Yeni bir projede formun üstüne bir tane buton ekle. Butonun adı Button1 olsun. Formun adı da Form1 olarak kalsın. Unit1 olarak kaydet ve aşağıdaki kodun tamamını kopyala:

Kod: Tümünü seç

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TDegiskenClass = class of TDegisken;
  TDegisken = class(TPersistent)
  private
    FAd: string;
    FDeger: Variant;
  protected
    function GetDeger: Variant; virtual; abstract;
    procedure SetDeger(AValue: Variant); virtual; abstract;
  public
    constructor Create; virtual;
    property Ad: string read FAd write FAd;
    property Deger: Variant read GetDeger write SetDeger;
  end;

  TIntDegisken = class(TDegisken)
    protected
      function GetDeger: Variant; override;
      procedure SetDeger(AValue: Variant); override;
    public
      constructor Create; override;
  end;

  TStringDegisken = class(TDegisken)
    protected
      function GetDeger: Variant; override;
      procedure SetDeger(AValue: Variant); override;
    public
      constructor Create; override;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    function CreateDegisken(AClassName: string): TDegisken;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


{ TIntDegisken }

constructor TIntDegisken.Create;
begin
  inherited;
  FDeger := 0;
end;

function TIntDegisken.GetDeger: Variant;
begin
  Result := VarAsType(FDeger, varInteger);
end;

procedure TIntDegisken.SetDeger(AValue: Variant);
begin
  try
    FDeger := VarAsType(AValue, varInteger);
  except
    on E:Exception do
      raise E;
  end;
end;

{ TDegisken }

constructor TDegisken.Create;
begin
  FDeger := varNull;
end;

{ TStringDegisken }

constructor TStringDegisken.Create;
begin
  inherited;
  FDeger := '';
end;

function TStringDegisken.GetDeger: Variant;
begin
  Result := VarAsType(FDeger, varString);
end;

procedure TStringDegisken.SetDeger(AValue: Variant);
begin
  FDeger := VarAsType(AValue, varString);
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  Deneme: TDegisken;
begin
  Deneme := CreateDegisken('TIntDegisken');
  Deneme.Deger := 3;
  ShowMessage(IntToStr(Deneme.Deger));
  Deneme.Free;

  Deneme := CreateDegisken('TStringDegisken');;
  Deneme.Deger := 'Bahadır Alkaç';
  ShowMessage(Deneme.Deger);
  Deneme.Free;

end;


function TForm1.CreateDegisken(AClassName: string): TDegisken;
var
  AClass: TPersistentClass;
begin
  AClass := FindClass(AClassName);
  Result := TDegiskenClass(AClass).Create;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  RegisterClass(TIntDegisken);
  RegisterClass(TStringDegisken);
end;

end.
Umarım bu tip bir çözüm işini görür.

İlla bellek yönetimli bir çözüm istiyorsan elbette o da mümkün. Ama projen ne kadar büyük olursa olsun yazacağın kod değmez. Çünkü o zaman örneğin int için bellekten sizeof(int) kadar yer alacaksın. Bunun için get/set fonksiyonları yazman gerekiyor. Fonksiyonların return/parametre tipleri birbirine uygun olmadığı için genel bir sınıf yapısı kullanamayacaksın. Dolayısıyla projeyi kodlarken çok daha fazla vakit kaybedeceksin (hem kodlama, hem de programın çalışma hızı).

Son olarak Pascal script (ya da diğer diller olabilir) kullanmak çok daha mantıklı. Ve hepsinden önemlisi, son kullanıcıya kod yazdıracaksak, biz ne iş yapacağız? Delphi'yi üreten firma da son kullanıcıya (yani bize :) ) kod yazdırmıyor mu? (Script yazmak biraz daha farklı elbette)

Kolay gelsin,
Bahadır Alkaç

Kolay gelsin,
Bahadır Alkaç
drf1
Üye
Mesajlar: 9
Kayıt: 11 Tem 2010 10:34

Re: Run time da degisken olusturma

Mesaj gönderen drf1 »

cevap yazan ve yardımcı olan arkadaşlara çok teşekkür ederim .son üç örnek gerçekten güzel görünüyor. Yardımcı olan arkadaşların ellerine sağlık .
Birde elimde bir ihtimal daha var .o da assembler ile yapmak .yani bu değişken tanımlamaları Delphi ye gökten zembille inmiyor ya?Onlarda bir şekilde tanımlıyorlar . Assembler da şöyle bir tanımlama var

DeğişkenAdı DW ?
yada
DeğişkenAdı DW 100

içeriği olmayan ve içeriğine 100 değeri atanan iki tane word değişkenin tanımı bu şekilde .Bunu bir procedure ile birleştirebilirsem olur diye düşünüyorum
Procedure TForm1.DAtama(Ad,tip:String);
Asm
Ad Dw ? //sadece word tanımı
End;
hepsi bu kadar gözüküyor .ama değil
Bu konumda label expected hatası veriyor.Eğer bilen arkdaş varsa , assembler da da yardım alabilirim.
Herkese iyi çalışmalar , çok teşekkürler.
drf1
Üye
Mesajlar: 9
Kayıt: 11 Tem 2010 10:34

Re: Run time da degisken olusturma

Mesaj gönderen drf1 »

OPT2000 hocam , oluşturduğumuz bu değişkenleri nasıl geri çağırabiliriz .yani name özelliği yok? Olsa da çağırma nazıl olacak ?
Kullanıcı avatarı
Opt2000
Üye
Mesajlar: 216
Kayıt: 09 Tem 2003 10:04

Re: Run time da degisken olusturma

Mesaj gönderen Opt2000 »

Selam,

Her yeni create ettiğiniz değişkeni bir listede tutacaksınız. O listeden de adına göre arama yapacaksınız. Bunu basit bir TList ile halledebileceğiniz gibi adam gibi bir class yazarak da çözebilirsiniz. Benim tavsiyem class yazmanız. Örneğin değişkenleri yönetecek class'da

Kod: Tümünü seç

  function VariableByName(VariableName: string): TDegisken; 
gibi bir fonksiyonla işi çok rahat çözebilirsiniz.

Bu arada, tam olarak ne yaptığınızı anlamamakla birlikte değişkenlerin scope'larına da dikkat etmeniz gerekebilir. Örneğin sizin tasarımınızda global değişken tanımlanabiliyorsa ve fonksiyonlar varsa, o zaman global tanımlanmış bir değişken ile fonksiyon içinde tanımlanmış bir değişken aynı isimde olabilir. Ya da kullanıcı recursive bir yapı kurabilir. Böyle bir durumda stack kullanmanız gerekecek. Yani iş öngördüğünüzden daha karışık bir hale gelebilir.

Sonuç olarak ben size yine bir script dili üzerine yoğunlaşmanızı tavsiye edeceğim.

Kolay gelsin,
Bahadır Alkaç
Cevapla