/ Forside / Teknologi / Udvikling / Delphi/Pascal / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Delphi/Pascal
#NavnPoint
oldwiking 603
jrossing 525
rpje 520
EXTERMINA.. 500
gandalf 460
gubi 270
DJ_Puden 250
PARKENSS 230
technet 210
10  jdjespers.. 200
Et par ? om OOP
Fra : Rune Simonsen


Dato : 28-01-03 04:38

Hej.

Jeg kommer fra Java og har lige et par hurtige om OOP i Delphi 6.

Jeg har et objekt a som indeholder[1] en masse objekter af typen b og
et objekt af typen b indeholder en masse objekter af typen c.

De skal så free'es i Delphi. Er det nok at free'e a, eller skal jeg
starte med at free'e alle c'er, så free'e alle b'er og så free'e a?

Hvad er konsekvensen hvis alt ikke bliver free'et korrekt? "død"
hukommelse, som ikke bliver frigivet antager jeg? Men bliver denne
hukommelse frigivet når mit program afsluttes eller sker dette først
efter genstart af maskinen?

Kender I desuden et godt sted på nettet hvor man kan læse mere om OOP
i delphi?

På forhånd tak.

[1] med "indeholder" mener jeg "har instance variable" altså
associering.

--

Rune Simonsen

 
 
David A. D. Konrad (28-01-2003)
Kommentar
Fra : David A. D. Konrad


Dato : 28-01-03 07:40

"Rune Simonsen" <rrs@nospam.dk> skrev i en meddelelse
news:3e35fb13$0$226$edfadb0f@dread16.news.tele.dk...

> Jeg kommer fra Java og har lige et par hurtige om OOP i Delphi 6.
>
> Jeg har et objekt a som indeholder[1] en masse objekter af typen b og
> et objekt af typen b indeholder en masse objekter af typen c.
>
> De skal så free'es i Delphi. Er det nok at free'e a, eller skal jeg
> starte med at free'e alle c'er, så free'e alle b'er og så free'e a?

Ja, der findes ingen garbagecollection i Delphi, så dine objekter er selv
ansvarlige for at rydde op efter sig selv. Du kunne jo placere oprydning af
de objekter et givent objekt ejer i den destroy-metode, så er du sikker på
oprydningen finder sted.

> Hvad er konsekvensen hvis alt ikke bliver free'et korrekt? "død"
> hukommelse, som ikke bliver frigivet antager jeg?

Ja.

> Men bliver denne
> hukommelse frigivet når mit program afsluttes eller sker dette først
> efter genstart af maskinen?

Det vil blot ligge og rode rundt - prøv selv at oprette nogle objekter og
mål den frie hukommelse før og efter, hvis ikke du free'er dem korrekt.





Rune Simonsen (29-01-2003)
Kommentar
Fra : Rune Simonsen


Dato : 29-01-03 20:50

On Tue, 28 Jan 2003 07:39:31 +0100, "David A. D. Konrad"
<david_konrad@hotmail.com> wrote:

> Ja, der findes ingen garbagecollection i Delphi, så dine objekter er selv
> ansvarlige for at rydde op efter sig selv. Du kunne jo placere oprydning af
> de objekter et givent objekt ejer i den destroy-metode, så er du sikker på
> oprydningen finder sted.

ok, en destroy metode? Hvad er det? Noget kode der bliver udført når
man kalder free på objektet? Hvordan laver jeg helt konkret sådan en?


Et lille bispørgsmål:

Jeg har en variabel c : TCykel

så skriver jeg
c := TCykel.create('rød'); (hvis det er sådan constructoren er lavet)
(gør en masse ting med c)
c := TCykel.create('blå'); (*)

Hvad sker der så med den røde cykel når jeg kalder (*)? Skal jeg
free'e c inden jeg kalder (*)?

Tak for hjælpen forresten :)

--

Rune Simonsen

David A. D. Konrad (30-01-2003)
Kommentar
Fra : David A. D. Konrad


Dato : 30-01-03 09:03

"Rune Simonsen" <rrs@nospam.dk> skrev i en meddelelse
news:3e38306d$0$148$edfadb0f@dread16.news.tele.dk...

> ok, en destroy metode? Hvad er det?

Ja, dét er en markant forskel fra java. Destroy er det konventionelle navn
på en klasses destructor, og er create's direkte modpol. Create
constructoren instantierer et nyt objekt af en given klasse, medens destroy
deallokerer objektet, dvs frigiver ressourcer brugt af objektet. Der findes
*altid* en destroy destructor i en delphi-klasse, eftersom alle klasser
implicit arver fra TObject. Men, hvis din klasse allokerer ressourcer, dvs
f.eks opretter en stribe objekter som ikke straks bliver nedlagt igen, er du
nødt til at override destroy, og sørge for at disse objekter bliver freet i
destroy metoden.

Denne klasse

TKlasse =class
public
a, b, c, d : integer;
farve : TColor;
procedure X;
function Y:string;
end;

behøver ikke en destructor - ja, ikke engang en constructor, da den ligeså
implicit nedarvede constructor kan bruges her, medens denne klasse :

TKlasse =class
private
FNavne : StringList;
procedure SetNavne(nyenavne:TStringList);
public
a, b, c, d : integer;
farve : TColor;
procedure X;
function Y:string;
published
property Navne : TStringList read FNavne write SetNavne;
end;

Både skal have en constructor og en destructor implementeret, da en
TStringList bør oprettes i create, og nedlægges i destroy, for at propertien
Navne skal kunne fungere korrekt. Det kunne ske således

constructor TKlasse.create;
begin
inherited create;
FNavne:=TStringList.create;
end;

destructor TKlasse.destroy;
begin
FNavne.free;
inherited destroy;
end;

Læg mærke til den omvendte rækkefølge. I create bør man først kalde
forældreklassens create inden man foretager sig noget som helst lokalt; i
destroy gør man først det lokale arbejde, og kalder så tilsidst
forældreklassens destroy.

Lars Dybdahl var inde på metoderne Free og FreeAndNil. Disse to metoder er
*ikke* destructors, men metoder der kalder destructoren, og henholdsvis
først chekker om den rent faktisk er assigned, samt efterfølgende sætter den
til at være nil.

Håber ovenstående måske lidt rodede forklaring gav lidt afklaring.

> Noget kode der bliver udført når
> man kalder free på objektet? Hvordan laver jeg helt konkret sådan en?

Det er destroy.

> Jeg har en variabel c : TCykel
>
> så skriver jeg
> c := TCykel.create('rød'); (hvis det er sådan constructoren er lavet)
> (gør en masse ting med c)
> c := TCykel.create('blå'); (*)
>
> Hvad sker der så med den røde cykel når jeg kalder (*)?

Den vil ikke blive nedlagt eller freet. Med mindre den er assigned til et
andet objekt vil den blot optage ressourcer.

> Skal jeg
> free'e c inden jeg kalder (*)?

Helt bestemt.





Rune Simonsen (30-01-2003)
Kommentar
Fra : Rune Simonsen


Dato : 30-01-03 18:08

On Thu, 30 Jan 2003 09:02:33 +0100, "David A. D. Konrad"
<david_konrad@hotmail.com> wrote:

> Håber ovenstående måske lidt rodede forklaring gav lidt afklaring.

Det var super-perfekt! Lige hvad jeg manglede. Mange tak!

(mit program allokerer 5-10 mb hukommelse, så det er nok bedst jeg får
lavet nogle destructors i en fart

--

Rune Simonsen

Lars B. Dybdahl (28-01-2003)
Kommentar
Fra : Lars B. Dybdahl


Dato : 28-01-03 18:10

Her et par tommelfingerregler, der sikrer korrekt memory håndtering. Der er
mange andre måder at gøre det på, men nedenstående regler er en god måde:

- Hvis b er en del af a, er a ejeren af b.
- Hvis et objekt oprettes i en konstruktor, skal det nedlægges i en
destruktor.
- Hvis et objekt oprettes i en OnShow event, skal det nedlægges i en OnHide
event.
- Hvis et objekt ejes af et array, anses ejeren af array'et for at være
ejeren af objektet.
- Hvis en funktion har til formål at oprette et objekt, bør dets navn starte
med "Create", og returværdien bør være objektet.
- Hvis a oprettes som en lokal variabel i en funktion/procedure, og ingen af
ovenstående regler gælder, er denne funktion som udgangspunkt ejer, og
objektet bør så også nedlægges i denne funktion/procedure.
- Benyt altid "FreeAndNil (a);" i stedet for "a.Free;". På denne måde får du
en invariant som er "objekter er altid nil eller peger på allokeret
memory". Det er yderst praktisk, især fordi både FreeAndNil() og .Free()
undlader at gøre noget, hvis variablen er nil i forvejen.

Det kan virke lidt irriterende at skulle holde styr på det, når man kommer
fra Java - til gengæld kommer belønningen ved deployment og hastighed.

Hilsen,

Lars.

--
Freelance programmør
Dybdahl Engineering: http://dybdahl.dk/
Delphi brugergruppen DAPUG: http://dapug.dk/




Rune Simonsen wrote:
> Jeg kommer fra Java og har lige et par hurtige om OOP i Delphi 6.
>
> Jeg har et objekt a som indeholder[1] en masse objekter af typen b og
> et objekt af typen b indeholder en masse objekter af typen c.
>
> De skal så free'es i Delphi. Er det nok at free'e a, eller skal jeg
> starte med at free'e alle c'er, så free'e alle b'er og så free'e a?
>
> Hvad er konsekvensen hvis alt ikke bliver free'et korrekt? "død"
> hukommelse, som ikke bliver frigivet antager jeg? Men bliver denne
> hukommelse frigivet når mit program afsluttes eller sker dette først
> efter genstart af maskinen?


David A. D. Konrad (28-01-2003)
Kommentar
Fra : David A. D. Konrad


Dato : 28-01-03 18:40

"Lars B. Dybdahl" <Lars@dybdahl.dk> skrev i en meddelelse
news:3e36b948$0$13221$edfadb0f@dread11.news.tele.dk...
> Her et par tommelfingerregler, der sikrer korrekt memory håndtering. Der
er
> mange andre måder at gøre det på, men nedenstående regler er en god måde:
>
> - Hvis b er en del af a, er a ejeren af b.
> - Hvis et objekt oprettes i en konstruktor, skal det nedlægges i en
> destruktor.
> - Hvis et objekt oprettes i en OnShow event, skal det nedlægges i en
OnHide
> event.
> - Hvis et objekt ejes af et array, anses ejeren af array'et for at være
> ejeren af objektet.

Hvordan kan et array "eje" et object?

> - Hvis en funktion har til formål at oprette et objekt, bør dets navn
starte
> med "Create", og returværdien bør være objektet.
> - Hvis a oprettes som en lokal variabel i en funktion/procedure, og ingen
af
> ovenstående regler gælder, er denne funktion som udgangspunkt ejer, og
> objektet bør så også nedlægges i denne funktion/procedure.

Der er slet og ret *intet* alternativ - imho!

> - Benyt altid "FreeAndNil (a);" i stedet for "a.Free;". På denne måde får
du
> en invariant som er "objekter er altid nil eller peger på allokeret
> memory". Det er yderst praktisk, især fordi både FreeAndNil() og .Free()
> undlader at gøre noget, hvis variablen er nil i forvejen.
>
> Det kan virke lidt irriterende at skulle holde styr på det, når man kommer
> fra Java - til gengæld kommer belønningen ved deployment og hastighed.

Og Java kan være "irriterende" at gå til fra Delphi, da man skal sætte sig
ind i 17 trilliarder klasser førend man kan kode noget fornuftigt ) Til
gengæld er java et herligt sprog, blot man har det rigtige udviklingsmiljø,
og det er jo klart et mere moderne sprog end
delphi/objectpascal/borlandpascal eller hvad de nu mener det skal hedde pt
(også imho).




Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408924
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste