/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Kan objekter delete sig selv ?
Fra : Robert Larsen


Dato : 07-04-03 15:00

Hey allesammen

Jeg er ved at strikke noget kode sammen, hvor jeg har indkapslet
Windows' og Linux' tråde som objekter. Når trådeobjekterne er færdige
med at køre, skal de 'delete' sig selv, men jeg ved ikke, om det er lovligt.
Jeg testede det med følgende kode:

----------------------------------------------------------------------------------
#include <iostream>

using std::endl;
using std::cout;

class Test
{
private:
Test() { }
public:
      //Det er den her jeg er i tvivl om
void destroy() { delete this; };

static Test * instanciate() { return new Test; }
};

int main(int argc, char ** argv)
{
Test * t = Test::instanciate();
cout << "Before" << endl;
t->destroy();
cout << "After" << endl;

return 0;
}
----------------------------------------------------------------------------------

Det virker fint, men kan man altid stole på det, eller var det bare held ?
Objekterne er ALTID dynamisk allokerede, og efter 'delete' bruges
objekternes member variabler og funktioner ikke mere.

VH
Robert


 
 
Ivan Johansen (07-04-2003)
Kommentar
Fra : Ivan Johansen


Dato : 07-04-03 19:48

Robert Larsen wrote:
> Jeg er ved at strikke noget kode sammen, hvor jeg har indkapslet
> Windows' og Linux' tråde som objekter. Når trådeobjekterne er færdige
> med at køre, skal de 'delete' sig selv, men jeg ved ikke, om det er
> lovligt.
Det er fuldt ud lovligt.

> Det virker fint, men kan man altid stole på det, eller var det bare held ?
> Objekterne er ALTID dynamisk allokerede, og efter 'delete' bruges
> objekternes member variabler og funktioner ikke mere.

Dette er lige netop betingelserne. Du må dog godt kalde ikke-virtuelle
og statiske funktioner.

Ivan Johansen


Anders J. Munch (08-04-2003)
Kommentar
Fra : Anders J. Munch


Dato : 08-04-03 11:10

"Ivan Johansen" <NG2@Padowan.dk> wrote:
> Robert Larsen wrote:
> > Jeg er ved at strikke noget kode sammen, hvor jeg har indkapslet
> > Windows' og Linux' tråde som objekter. Når trådeobjekterne er færdige
> > med at køre, skal de 'delete' sig selv, men jeg ved ikke, om det er
> > lovligt.
> Det er fuldt ud lovligt.
>
> > Det virker fint, men kan man altid stole på det, eller var det bare held ?
> > Objekterne er ALTID dynamisk allokerede, og efter 'delete' bruges
> > objekternes member variabler og funktioner ikke mere.
>
> Dette er lige netop betingelserne. Du må dog godt kalde ikke-virtuelle
> og statiske funktioner.

Sædvanligvis går det godt at kalde ikke-virtuelle metoder i et
ikke-eksisterende objekt, men det er ikke sanktioneret af standarden.

mvh. Anders



William d'foe (08-04-2003)
Kommentar
Fra : William d'foe


Dato : 08-04-03 12:48

> Sædvanligvis går det godt at kalde ikke-virtuelle metoder i et
> ikke-eksisterende objekt, men det er ikke sanktioneret af standarden.

Det gælder dog kun hvis metoden ikke piller ved objekts egne data/variabler.
Statiske variabler og variabler erklæret udenfor objektet er ikke noget
problem, men objektets egne variabler er som sådan ikke allokeret og "this"
kan derfor pege på hvad som helst.



Ivan Johansen (08-04-2003)
Kommentar
Fra : Ivan Johansen


Dato : 08-04-03 13:30

Anders J. Munch wrote:
> Sædvanligvis går det godt at kalde ikke-virtuelle metoder i et
> ikke-eksisterende objekt, men det er ikke sanktioneret af standarden.
Jeg var ellers sikker på at det var tilladt i standarden, men jeg tager
muligvis fejl. Kan du henvise mig til hvor det står i standarden, da jeg
ikke lige kan finde det.

Ivan Johansen


Anders J. Munch (08-04-2003)
Kommentar
Fra : Anders J. Munch


Dato : 08-04-03 17:40

"Ivan Johansen" <NG2@Padowan.dk> wrote:
> Anders J. Munch wrote:
> > Sædvanligvis går det godt at kalde ikke-virtuelle metoder i et
> > ikke-eksisterende objekt, men det er ikke sanktioneret af standarden.
> Jeg var ellers sikker på at det var tilladt i standarden, men jeg tager
> muligvis fejl. Kan du henvise mig til hvor det står i standarden, da jeg
> ikke lige kan finde det.

Det står ikke direkte nogen steder.

Et metodekald med implicit this som:
metode();
er ækvivalent med
(*this).metode(); /* ifølge 5.2.2 */

Efter "delete this" så peger "this" ikke længere på et gyldigt objekt,
og "*this" er derfor undefined behaviour.

mvh. Anders




Ivan Johansen (08-04-2003)
Kommentar
Fra : Ivan Johansen


Dato : 08-04-03 20:10

Anders J. Munch wrote:
> Det står ikke direkte nogen steder.
>
> Et metodekald med implicit this som:
> metode();
> er ækvivalent med
> (*this).metode(); /* ifølge 5.2.2 */
>
> Efter "delete this" så peger "this" ikke længere på et gyldigt objekt,
> og "*this" er derfor undefined behaviour.

Okay, det kan jeg godt se.
Det undrer mig bare at der ikke noget sted står at "delete this" er
tilladt, men det skal nok ses ud fra at this er en almindelig pointer.

Ivan Johansen


Bo Lorentsen (09-04-2003)
Kommentar
Fra : Bo Lorentsen


Dato : 09-04-03 06:57

Ivan Johansen wrote:

> Okay, det kan jeg godt se.
> Det undrer mig bare at der ikke noget sted står at "delete this" er
> tilladt, men det skal nok ses ud fra at this er en almindelig pointer.
Det er rigtigt at "this" er et implicit parameter til alle member
functioner, men hvis du ikke refererer til det har det ikke nogen
praktisk betydning. Men hvis du tilgår en member variable efter at havde
lavet "delete this" er du selv unde om det

Det er et ofte diskuteret emne, som af og til kan få samme status som
goto diskutionen

/BL


Anders J. Munch (09-04-2003)
Kommentar
Fra : Anders J. Munch


Dato : 09-04-03 09:58

"Bo Lorentsen" <bl@nospam.lue.dk> wrote:
> Ivan Johansen wrote:
>
> > Okay, det kan jeg godt se.
> > Det undrer mig bare at der ikke noget sted står at "delete this" er
> > tilladt, men det skal nok ses ud fra at this er en almindelig pointer.
> Det er rigtigt at "this" er et implicit parameter til alle member
> functioner, men hvis du ikke refererer til det har det ikke nogen
> praktisk betydning.

Jeg synes nu at den dialogboks med titlen "CodeGuard Error" som jeg
ville få hvis jeg prøvede det, er en praktisk betydning.

mvh. Anders



Robert Larsen (09-04-2003)
Kommentar
Fra : Robert Larsen


Dato : 09-04-03 10:10

Anders J. Munch wrote:
> "Bo Lorentsen" <bl@nospam.lue.dk> wrote:
>
>>Ivan Johansen wrote:
>>
>>
>>>Okay, det kan jeg godt se.
>>>Det undrer mig bare at der ikke noget sted står at "delete this" er
>>>tilladt, men det skal nok ses ud fra at this er en almindelig pointer.
>>
>>Det er rigtigt at "this" er et implicit parameter til alle member
>>functioner, men hvis du ikke refererer til det har det ikke nogen
>>praktisk betydning.
>
>
> Jeg synes nu at den dialogboks med titlen "CodeGuard Error" som jeg
> ville få hvis jeg prøvede det, er en praktisk betydning.
>
> mvh. Anders
>
>
Enig. Jeg tror ikke at man skal være sikker på at tilgang til member
funktioner altid går godt, og jeg er sikker på at man skal holde sig fra
member variable, men så længe man kan lave en "delete this;" så er jeg
godt tilfreds. Det er alligevel det sidste objektet gør.
Faktisk er det et andet objekt der delete'r men én af det slettede
objekts member funktioner er på trådens stak når det sker. Det var det
jeg ikke var sikker på var lovligt.

VH
Robert


Bo Lorentsen (09-04-2003)
Kommentar
Fra : Bo Lorentsen


Dato : 09-04-03 11:49

Anders J. Munch wrote:

> Jeg synes nu at den dialogboks med titlen "CodeGuard Error" som jeg
> ville få hvis jeg prøvede det, er en praktisk betydning.
Hmm, det lyder lidt platform specifikt, og det er da heller ikke uden
problemer, se f.eks. :

http://www.cs.ntu.edu.au/homepages/rsvp/sit112/FAQ/section9.html

Under Q39

Men ellers kan jeg ikke se problemet

/BL


Benny Andersen (11-04-2003)
Kommentar
Fra : Benny Andersen


Dato : 11-04-03 00:58

On Tue, 8 Apr 2003 18:40:17 +0200, "Anders J. Munch"
<andersjm@dancontrol.dk> wrote:

>"Ivan Johansen" <NG2@Padowan.dk> wrote:
>> Anders J. Munch wrote:
>> > Sædvanligvis går det godt at kalde ikke-virtuelle metoder i et
>> > ikke-eksisterende objekt, men det er ikke sanktioneret af standarden.
>> Jeg var ellers sikker på at det var tilladt i standarden, men jeg tager
>> muligvis fejl. Kan du henvise mig til hvor det står i standarden, da jeg
>> ikke lige kan finde det.
>
>Det står ikke direkte nogen steder.
>
>Et metodekald med implicit this som:
> metode();
>er ækvivalent med
> (*this).metode(); /* ifølge 5.2.2 */

Hvad betyder 'med implicit this'? Alle ikke statiske metoder afvikles
med this værdi adgang, men det undrer mig hvis standarden foreskriver
ovenstående for ikke virtuelle funktioner (jeg har ikke standarden)

/** MSVC 6.0 */
struct A
{
   int val() { return 45; }
};

int main()
{
   return ((A*)0)->val();
   // igen dereferering, alene typen tæller
}



>Efter "delete this" så peger "this" ikke længere på et gyldigt objekt,
>og "*this" er derfor undefined behaviour.
>
>mvh. Anders
>
>


Mogens Hansen (11-04-2003)
Kommentar
Fra : Mogens Hansen


Dato : 11-04-03 06:02


"Benny Andersen" <be9@worldoffline.dk> wrote

[8<8<8]
> int main()
> {
> return ((A*)0)->val();
> // igen dereferering, alene typen tæller
> }

Med en forståelse af den underliggende mekanik er det ikke underligt at det
tilsyneladende virker.
Men der er ingen garanti for at det virker på en tilnærmelsesvis fornuftig
måde - præcis som alle andre tilfælde hvor man bruger en pointer med ugyldig
værdi.
Opførslen kan nemt ændre sig hvis du opgraderer compiler, skifter platform
eller lignende.

Kort sagt, det er rigtigt grimt, farligt og unødvendigt.

Venlig hilsen

Mogens Hansen



Benny Andersen (17-04-2003)
Kommentar
Fra : Benny Andersen


Dato : 17-04-03 11:19

On Fri, 11 Apr 2003 07:02:08 +0200, "Mogens Hansen"
<mogens_h@dk-online.dk> wrote:

>
>"Benny Andersen" <be9@worldoffline.dk> wrote
>
>[8<8<8]
>> int main()
>> {
>> return ((A*)0)->val();
>> // igen dereferering, alene typen tæller
>> }
>
>Med en forståelse af den underliggende mekanik er det ikke underligt at det
>tilsyneladende virker.
>Men der er ingen garanti for at det virker på en tilnærmelsesvis fornuftig
>måde - præcis som alle andre tilfælde hvor man bruger en pointer med ugyldig
>værdi.
>Opførslen kan nemt ændre sig hvis du opgraderer compiler, skifter platform
>eller lignende.
>
>Kort sagt, det er rigtigt grimt, farligt og unødvendigt.
>
>Venlig hilsen
>
>Mogens Hansen
>
Du udtrykker dig meget indirekte!
Er det rigtigt forstået at standarden i 5.2.2 angiver at man bør
forvente-, og at compilere skal implementere alle klasser med med
'this' pegende på en vptr.
Eller spurgt på en anden måde: opfylder MSVC 6.0 og GCC 2.96 ikke
standarden på dette punkt, hvor 'this', for ikke virtuelle klassers
vedkommende, peger på første attribut.

Mvh Benny

Mogens Hansen (20-04-2003)
Kommentar
Fra : Mogens Hansen


Dato : 20-04-03 14:28


"Benny Andersen" <be9@worldoffline.dk> wrote

[8<8<8<]
> Er det rigtigt forstået at standarden i 5.2.2 angiver at man bør
> forvente-, og at compilere skal implementere alle klasser med med
> 'this' pegende på en vptr.

Nej, ikke så vidt jeg kan se.
Hvorfra mere præcist har du det indtryk ?

Dels vil jeg blive overrasket hvis C++ Standarden stiller krav om at der
skal findes en vptr eller virtuelle tabeller. Det er op til den enkelte
implementering hvordan valg af hvilken funktion, der skal kaldes er
implementeres.

Dels er det lang fra alle klasser der har virtuelle metoder og dermed behov
for en vptr (eller tilsvarende mekanisme)

> Eller spurgt på en anden måde: opfylder MSVC 6.0 og GCC 2.96 ikke
> standarden på dette punkt, hvor 'this', for ikke virtuelle klassers
> vedkommende, peger på første attribut.

Jeg antager at du mener "klasser med en eller flere virtuelle metoder" og
ikke "virtuelle klasser".
Så vidt jeg kan se stiller C++ Standarden ikke nogen krav i den retning, og
dermed er der ikke noget compilerne skal overholde.


Venlig hilsen

Mogens Hansen



Rasmus Christian Kaa~ (10-04-2003)
Kommentar
Fra : Rasmus Christian Kaa~


Dato : 10-04-03 10:40

> Det virker fint, men kan man altid stole på det, eller var det bare held ?
> Objekterne er ALTID dynamisk allokerede, og efter 'delete' bruges
> objekternes member variabler og funktioner ikke mere.


Ville det ikke være pænere at bruge nogen datastrukturer der rydder op efter
sig selv? f.eks. auto_ptr eller lign?



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