|
| Exceptions i .Create Fra : Rasmus Wätjen |
Dato : 28-11-00 11:37 |
|
Hejsa.
I hjælpen står der for TObject.Create, at såfremt der rejses exceptions i en
constructor, så kaldes objektes destructor med det samme.
Det er jo ret godt, men hvad nu hvis en constructor for en klasse kalder
constructoren for en anden klasse, og der i den anden opstår exceptions. Så
vil der ifølge hjælpen blive kaldt destructoren for den anden klasse, men
vil denne exception genrejses, så den første klasses destructor også
kaldes? - Eller vil den første klasse gå videre som om ingenting var sket,
bortset fra at dens field med den anden klasse vil være udefineret?
Er der nogen der har erfaring med ovenstående, så er jeg meget interesseret.
Mvh Rasmus
| |
Lars Bargmann (28-11-2000)
| Kommentar Fra : Lars Bargmann |
Dato : 28-11-00 12:01 |
|
Så vidt jeg ved bliver den re-raised....
Men, det er en af de største fejl man ser folk lave....
Tjek ALTID i din destructor om et object eksisterer inden du forsøger at
free'e det....
Hvis constructoren opretter 10 objecter, men raiser en exception på nummer
4, er de sidste 6 (7, for at være præcis) jo ikke oprettet, og derfor kan
der ikke kaldes free på dem.....
Skummelt, men sådan er det....
"Rasmus Wätjen" <rw@erasethis.solit.dk> wrote in message
news:9WLU5.50$Ow2.1608@news.get2net.dk...
> Hejsa.
> I hjælpen står der for TObject.Create, at såfremt der rejses exceptions i
en
> constructor, så kaldes objektes destructor med det samme.
> Det er jo ret godt, men hvad nu hvis en constructor for en klasse kalder
> constructoren for en anden klasse, og der i den anden opstår exceptions.
Så
> vil der ifølge hjælpen blive kaldt destructoren for den anden klasse, men
> vil denne exception genrejses, så den første klasses destructor også
> kaldes? - Eller vil den første klasse gå videre som om ingenting var sket,
> bortset fra at dens field med den anden klasse vil være udefineret?
>
> Er der nogen der har erfaring med ovenstående, så er jeg meget
interesseret.
>
> Mvh Rasmus
>
>
| |
Martin Frostholm (28-11-2000)
| Kommentar Fra : Martin Frostholm |
Dato : 28-11-00 12:18 |
|
Det er nu ikke helt rigtigt. Free undersøger først om objektets reference er
nil. Hvis ikke kaldes Destroy på objektet.
--
Martin Frostholm
mailto:martin@frostholm.com
"Lars Bargmann" <lars.bargmann@mail.tele.dk> wrote in message
news:90035q$psj$1@news.inet.tele.dk...
> Så vidt jeg ved bliver den re-raised....
> Men, det er en af de største fejl man ser folk lave....
> Tjek ALTID i din destructor om et object eksisterer inden du forsøger at
> free'e det....
> Hvis constructoren opretter 10 objecter, men raiser en exception på nummer
> 4, er de sidste 6 (7, for at være præcis) jo ikke oprettet, og derfor kan
> der ikke kaldes free på dem.....
> Skummelt, men sådan er det....
>
> "Rasmus Wätjen" <rw@erasethis.solit.dk> wrote in message
> news:9WLU5.50$Ow2.1608@news.get2net.dk...
> > Hejsa.
> > I hjælpen står der for TObject.Create, at såfremt der rejses exceptions
i
> en
> > constructor, så kaldes objektes destructor med det samme.
> > Det er jo ret godt, men hvad nu hvis en constructor for en klasse kalder
> > constructoren for en anden klasse, og der i den anden opstår exceptions.
> Så
> > vil der ifølge hjælpen blive kaldt destructoren for den anden klasse,
men
> > vil denne exception genrejses, så den første klasses destructor også
> > kaldes? - Eller vil den første klasse gå videre som om ingenting var
sket,
> > bortset fra at dens field med den anden klasse vil være udefineret?
> >
> > Er der nogen der har erfaring med ovenstående, så er jeg meget
> interesseret.
> >
> > Mvh Rasmus
> >
> >
>
>
| |
David A. D. Konrad (28-11-2000)
| Kommentar Fra : David A. D. Konrad |
Dato : 28-11-00 12:14 |
|
Rasmus Wätjen wrote in message <9WLU5.50$Ow2.1608@news.get2net.dk>...
>Hejsa.
>I hjælpen står der for TObject.Create, at såfremt der rejses exceptions i
en
>constructor, så kaldes objektes destructor med det samme.
>Det er jo ret godt, men hvad nu hvis en constructor for en klasse kalder
>constructoren for en anden klasse, og der i den anden opstår exceptions. Så
>vil der ifølge hjælpen blive kaldt destructoren for den anden klasse, men
>vil denne exception genrejses, så den første klasses destructor også
>kaldes? - Eller vil den første klasse gå videre som om ingenting var sket,
>bortset fra at dens field med den anden klasse vil være udefineret?
Det sidste, vil jeg umiddelbart mene.
T1 =class(TObject)
constructor create;
end;
T2 =class(TObject)
test : T1;
constructor create;
procedure I_Live;
end;
constructor T1.create;
var s:string;
begin
inherited;
s[123]:='B'; //her rejses exception
end;
constructor T2.create;
begin
inherited;
test:=T1.create; //her dør T1
end;
procedure T2.I_Live;
begin
messagedlg('T2 lever!', mtInformation,[mbOk],0);
end;
procedure TForm1.FormCreate(Sender: TObject);
var T:T2;
begin
T:=T2.create;
T.I_Live; //kaldes aldrig, da exception reraises
end;
Da T1 kaldes reraises exceptionen ganske vist, men T2 destrueres ikke.
Istedet vil
constructor T2.create;
begin
inherited;
try
test:=T1.create; //her dør T1
except
end;
end;
fange fejlen, og I_Live bliver kaldt korrekt. Man bør altid sætte
try..except om createerklæringer i en constructor. Om ikke andet, så for at
det kan dannes et exceptionframe så fejlen fanges, og så man er sikker på at
alle klassens felter initialiseres.
hilsen,
| |
Jesper Andersen (29-11-2000)
| Kommentar Fra : Jesper Andersen |
Dato : 29-11-00 22:46 |
|
konrad@dadk.dk (David A. D. Konrad) wrote in
<1sMU5.11917$zs.317961@twister.sunsite.auc.dk>:
>fange fejlen, og I_Live bliver kaldt korrekt. Man bør altid sætte
>try..except om createerklæringer i en constructor. Om ikke andet, så for
>at det kan dannes et exceptionframe så fejlen fanges, og så man er
>sikker på at alle klassens felter initialiseres.
Man bør egentlig gøre noget lign:
try
dittendat.create;
try
//do something
finally
dittendat.free;
end;
except
end;
Så er man sikker på at hvis der går ged i programmet, bliver dittendat
free'et.
Hvad mener du i øvrigt med "så man er
sikker på at alle klassens felter initialiseres"?
/Data
| |
David A. D. Konrad (30-11-2000)
| Kommentar Fra : David A. D. Konrad |
Dato : 30-11-00 09:08 |
|
Jesper Andersen wrote in message <8FFBE4390datakrikkitdk@212.54.64.134>...
>konrad@dadk.dk (David A. D. Konrad) wrote in
><1sMU5.11917$zs.317961@twister.sunsite.auc.dk>:
>
>
>>fange fejlen, og I_Live bliver kaldt korrekt. Man bør altid sætte
>>try..except om createerklæringer i en constructor. Om ikke andet, så for
>>at det kan dannes et exceptionframe så fejlen fanges, og så man er
>>sikker på at alle klassens felter initialiseres.
>
>Man bør egentlig gøre noget lign:
>
>try
> dittendat.create;
> try
> //do something
> finally
> dittendat.free;
> end;
>except
>end;
Ja, men det går jo ikke i en create - eller jo, det gør det da, men så er
klassen ikke tilgængelig senere hen. Typisk er klasser der oprettes i en
klasses create enten hjælpeklasser, containere eller properties. Det _kan_
da være at en klasse blot skal bruges en enkelt gang ved opstart, men da vil
jeg anbefale at koden placeres i Loaded, således at create-constructoren har
færrest mulige potentielle fejlkilder.
>Så er man sikker på at hvis der går ged i programmet, bliver dittendat
>free'et.
>
>Hvad mener du i øvrigt med "så man er
>sikker på at alle klassens felter initialiseres"?
At jeg antager, at den klasse der skal oprettes er property i klassen. Hvis
oprettelsen af T1 fejler, mangler T2 et felt, dvs en property.
hilsen,
| |
|
|