2010-07-11 14 views
9

Delphi'de karşılıklı başvuru kayıtları oluşturmak için herhangi bir çalışma var mı? kayıt türlerininKarşılıklı referans kayıtları Delphi (Win32)

MyRec1 = record 
    arr: MyRec2Array; 
end; 

MyRec2 = record 
    mr: MyRec1; 
end; 

MyRec2Array = array of MyRec2; 

Görünüşe ileri beyan

MyRec2 = record; 

Win32 için Delphi çalışmaz: Burada kodun basitleştirilmiş versiyonu.

Kayıtlar yerine sınıflara geçmek iyi değildir, çünkü bu bellek tüketimini ve kod karmaşıklığını artıracaktır, bu yüzden kayıtlarla kalmayı tercih ederim.

Herhangi bir öneriniz var mı?

+3

Olası yinelenen: http://stackoverflow.com/questions/2420650/cross-reference-between-delphi-records –

+1

Bu hiç mantıklı değil. Her bir MyRec2Array öğesinin uzunluğunun sabit ve sıfır olmadığını varsayarsak, sonsuz sayıda bayt içerecek bir veri yapısı oluşturmaya çalışıyorsunuzdur ... –

+1

@Andreas Rejbrand - MyRec2Array * dinamik * dizisidir. – Alex

cevap

14

Kayıtlar, referans türleri değil, değer türleridir. Bu, daha büyük bir veri yapısının üyeleri olarak kullanılan tüm kayıtların, bir işaretçi yerine yapının içine sıralı olarak yerleştirildiği anlamına gelir. Birbirini içeren iki kayıt oluşturmaya çalışmak, derleyiciyi, kayıtların yapısını anlamaya çalışırken sonsuz bir döngüye fırlatacaktır. Muhtemelen bir rekor beyan edememenin nedeni budur ve burada bir referans tipi (dinamik dizi) yerleştirmeye çalışsanız bile, dil kurallarını ihlal edemezsiniz.

Ama ne yapabilirim böylece gibi bir ileri beyanı gibi bir işaretçi-to-kayıt türü bildirmek olduğunu: Elbette

PMyRec2 = ^MyRec2 
... 
MyRec2 = record 
    ... 
end; 

, sen kayıtlarına işaretçileri kullanmaya başladığınızda, size tahsis konusunda endişelenmenize gerek ve belleği serbest bırakarak, sınıfları kullanmamaktan kaçınmaya çalıştığınız kod karmaşıklığı projenizde görünür. Alt satır: bunu derslerle yapın. Her ikisi de olmasa da, kayıtlardan birini yapın. Bu gerçekten en basit yol.

Ekstra bellek yükü ihmal edilebilir. Her bir nesne için, bir nesneye işaretçiler için ihtiyacınız olan bir işaretçiye, ayrıca D2009'dan önce bir tane gizli alana (4 byte) veya D2009 veya daha sonraki sürümlerine (8 bayt) işaretçi çıkar. Bu hiç de fazla değil.

+2

+1, değer türünün gerekçelerini ve –

+0

işaretçileri kullanarak geçici çözümü belirtmek için Pointer çalışmayla aradığım şeydir. Ayrıca her bir TObject örneğinin yaklaşık 30 bayt olduğunu düşünüyorum. Nereden aldığımı bilmiyorum ama yazıyı okuduktan sonra D2007'de okudum ve gerçekten 4 bayt. Yani kesinlikle haklısın. Çok teşekkürler! – Max

+0

Dynarray zaten dinamik bir tür olduğundan, değer türü sınırlamasının burada geçerli olmadığını unutmayın. Bu muhtemelen "serginin" çözümünün işe yaramasıdır. –

4

Mason'la tamamen aynı fikirde olmakla birlikte, sınırlamayı aşmanın bir yolu var. Temel olarak, MyRec2 bildirildikten sonra gerekli işlevleri tanımlamak için bir kayıt yardımcı programını kullanabilirsiniz.

type 
    MyRec1 = record 
    arr: array of byte; 
    end; 

    MyRec2 = record 
    mr: MyRec1; 
    end; 

    MyRec1Helper = record helper for MyRec1 
    procedure AllocateMyRec2(numItems: integer); 
    function GetMyRec2(i: integer): MyRec2; 
    procedure SetMyRec2(i: integer; const value: MyRec2); 
    property Rec2[i: integer]: MyRec2 read GetMyRec2 write SetMyRec2; 
    end; 

procedure MyRec1Helper.AllocateMyRec2(numItems: integer); 
begin 
    SetLength(arr, numItems * SizeOf(myRec2)); 
end; 

function MyRec1Helper.GetMyRec2(i: integer): MyRec2; 
begin 
    Move(arr[i*SizeOf(MyRec2)], Result, SizeOf(MyRec2)); 
end; 

procedure MyRec1Helper.SetMyRec2(i: integer; const value: MyRec2); 
begin 
    Move(value, arr[i*SizeOf(MyRec2)], SizeOf(MyRec2)); 
end; 

var 
    my: MyRec2; 

begin 
    my.mr.AllocateMyRec2(2); 
    my.mr.Rec2[0].mr.AllocateMyRec2(3); 
end. 
4

soru bana şaka gibi görünüyor - o sonsuz türü tanımı döngü ilgili, karşılıklı referanslarla ilgili değil. nasıl Yukarıdaki kayıt türü kullanmak

type 
    MyRec2 = record 
    type 
    MyRec2Array = array of MyRec2; 
    type 
    MyRec1 = record 
     arr: MyRec2Array; 
    end; 
    var 
    mr: MyRec1; 
    end; 

Ama: Karşılıklı referanslar gelince, onlar bir kayıt içinde türlerini tanımlayarak çözülebilir (ben 2009 Delphi kullanılacak)? Gerçekten komik. :)

procedure TForm1.Button1Click(Sender: TObject); 
var 
    R: MyRec2; 

begin 
    SetLength(R.mr.arr, 1); 
// R.mr.arr[0]:= ???; 
end;