Toon posts:

[c++] Destructing...

Pagina: 1
Acties:

Verwijderd

Topicstarter
Worden in BC6 de Tforms enz. door BC6 zelf uit het geheugen verwijdert? Of moet ik zelf zoiets als hieronder in de class definitie zetten. Mijn vorige problemen heb ik ondertussen zelf al opgelost...

C++:
1
2
3
4
 ~Tform:Public{
delete een_of_andere_array;
delete TForm; //dit is volgens mij per definitie al fout.(er was geloof ik al een ander commando voor, maar die ben ik vergeten).
}


Ik wil dus dat er bij het afsluiten van mijn (child)Form geen dingen van dat Form nog in het geheugen staan en ik wil weten hoe ik een array die ik in de class heb gedefinieerd(opl. vorige probleem), op het moment dat iemand het venster afsluit, de array verwijderd.

Hoe kan ik dit doen?

  • Remenic
  • Registratie: Juni 2001
  • Laatst online: 09-08 20:06
delete [] arreej;

  • whoami
  • Registratie: December 2000
  • Laatst online: 21:36
Als je de form sluit, wordt het geheugen van die form vrijgegeven + het geheugen van de controls op die form.
Geheugen dat gealloceerd werd door eigen objecten enzo, moet je zelf nog vrijgeven.

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 21:36
* whoami vind het wel een rare destructor - definitie.
Normaal doe je het toch zo:
code:
1
2
3
4
TForm1::~TForm1
{
   delete[] array;
}


Die delete TForm moet er al niet staan. Trouwens, TForm is volgens mij niet de naam van het object. Je zou kunnen doen:
code:
1
delete this;

Als je het object zelf wilt vrijgeven.

Maar, die 'opruimcode' kan je imho ook gewoon in de TForm::Close event zetten ipv in een destructor.

https://fgheysels.github.io/


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

whoami schreef op 06 December 2002 @ 15:35:
Je zou kunnen doen:
code:
1
delete this;

Als je het object zelf wilt vrijgeven.

Maar, die 'opruimcode' kan je imho ook gewoon in de TForm::Close event zetten ipv in een destructor.
Erm wil je beide dingen NOOOOIT doen tenzij je HEEEEEL goed weet waar je mee bezig bent?!? Beide gevallen illustreren namelijk het concept 'poten onder de stoel vandaan zeggen' heel goed, wat vrijwel altijd resulteert in Access Violations.

En om de originele vraag te beantwoorden:
Worden in BC6 de Tforms enz. door BC6 zelf uit het geheugen verwijdert?
Ja. Hoef je dus niets aan te doen.

Professionele website nodig?


  • whoami
  • Registratie: December 2000
  • Laatst online: 21:36
curry684 schreef op 06 December 2002 @ 15:42:
[...]

Erm wil je beide dingen NOOOOIT doen tenzij je HEEEEEL goed weet waar je mee bezig bent?!? Beide gevallen illustreren namelijk het concept 'poten onder de stoel vandaan zeggen' heel goed, wat vrijwel altijd resulteert in Access Violations.
Een delete this; nee, idd dat doe je beter niet.
Maar in de code van de TS stond
code:
1
delete TForm;

wat niet goed is. En hij heeft zelf al aan dat hij dat waarschijnlijk beter niet doet.
En om de originele vraag te beantwoorden:

[...]

Ja. Hoef je dus niets aan te doen.


Stel dat ik in m'n form een aantal objecten heb. Neem nou dat ik een ListView heb, met in de Data property van ieder listitem een verwijzing naar een custom object, dan moet ik deze toch allemaal zelf vrijgeven als de form gesloten wordt?

https://fgheysels.github.io/


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

whoami schreef op 06 December 2002 @ 15:45:
Stel dat ik in m'n form een aantal objecten heb. Neem nou dat ik een ListView heb, met in de Data property van ieder listitem een verwijzing naar een custom object, dan moet ik deze toch allemaal zelf vrijgeven als de form gesloten wordt?
Mmm de vraag ging over "TForms enz.", en alle TComponent derivants (zoals TForm, TListView, TTimer etc) worden automatisch weggeflikkerd. Eventuele helperclasses van jezelf moet je idd wel in destructor wegkieperen.

Professionele website nodig?


  • whoami
  • Registratie: December 2000
  • Laatst online: 21:36
curry684 schreef op 06 December 2002 @ 16:17:
[...]

Mmm de vraag ging over "TForms enz.", en alle TComponent derivants (zoals TForm, TListView, TTimer etc) worden automatisch weggeflikkerd. Eventuele helperclasses van jezelf moet je idd wel in destructor wegkieperen.



Nee hoor, hij vroeg of hij die array die hij had zelf moest wegkieperen. :P

https://fgheysels.github.io/


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

whoami schreef op 06 december 2002 @ 15:33:
Als je de form sluit, wordt het geheugen van die form vrijgegeven + het geheugen van de controls op die form.
Geheugen dat gealloceerd werd door eigen objecten enzo, moet je zelf nog vrijgeven.
Ik wil het zelfs nog iets genuanceerder vertellen:

Tenzij er on de OnClose Action := caFree; staat wordt een form niet vrijgegeven bij een Close maar alleen geHide. Als je het MainForm wordt wel vrijgegeven als ie gesloten wordt, waarna de applicatie sluit.

Via een Owner structuur worden ook andere componenten en forms automatisch vrijgegeven. Deze wordt meestal via de constructor meegegeven.

In de regel moet je alles vrijgeven wat je zelf creeer. Wat BCB voor je creeerd niet.

Een object geeft in de regel nooit zichzelf vrij zoals al gezegt.

delete [] een_of_andere_array;
delete Form1;

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Topicstarter
whoami schreef op 06 december 2002 @ 16:20:

[...]



Nee hoor, hij vroeg of hij die array die hij had zelf moest wegkieperen. :P
Inderdaad, en moet dat? :9~

Ik stop in die Dynamic_array(ja, het is geen gewone, maar ik denk ik haal er niet meer bij dan nodig) een aantal tekstvelden, de zogenaamde TEdit objecten. Die heb ik dan dus custom gemaakt en het aantal is afhankelijk van een waarde die nader te bepalen is (bijv. 10). Het lijkt dat als ik de array weggooi, ik de objecten nog heb, en alleen de verwijzingen heb weggegooid. Dus hoe gooi ik die dan weg? :?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 03:07
Verwijderd schreef op 06 December 2002 @ 21:13:
Inderdaad, en moet dat? :9~

Ik stop in die Dynamic_array(ja, het is geen gewone, maar ik denk ik haal er niet meer bij dan nodig) een aantal tekstvelden, de zogenaamde TEdit objecten. Die heb ik dan dus custom gemaakt en het aantal is afhankelijk van een waarde die nader te bepalen is (bijv. 10). Het lijkt dat als ik de array weggooi, ik de objecten nog heb, en alleen de verwijzingen heb weggegooid. Dus hoe gooi ik die dan weg? :?
Het hangt er allemaal vanaf of je array dynamisch gealloceerd is, en of je array-elementen dat zijn. De volgende code demonstreert hoe je de verschillende variabelen zou aanmaken en opruimen.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Blaat {
    Object a[10];
    Object *b;
    Object *c[10];
    Object **d;

public:

    Blaat()
    {
        b = new Object[10];

        for(int n = 0; n < 10; ++n)
            c[n] = new Object();

        d = new (Object*)[10];
        for(int n = 0; n < 10; ++n)
            d[n] = new Object();
    }

    ~Blaat()
    {
        delete[] b;

        for(int n = 0; n < 10; ++n)
            delete c[n];

        for(int n = 0; n < 10; ++n)
            delete d[n];
        delete[] d;
    }

};

In alle gevallen beschik je over een array met 10 geldige (gealloceerde en geintialiseerde) objecten.

[ Voor 3% gewijzigd door Soultaker op 06-12-2002 21:35 ]


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 24-08 22:38
curry684 schreef op 06 december 2002 @ 15:42:
[...]

Erm wil je beide dingen NOOOOIT doen tenzij je HEEEEEL goed weet waar je mee bezig bent?!? Beide gevallen illustreren namelijk het concept 'poten onder de stoel vandaan zeggen' heel goed, wat vrijwel altijd resulteert in Access Violations.
Wat is precies het probleem bij een 'delete this' dan ? ( Behalve dat je moet oppassen met eventuele referenties naar het 'this' object buiten het object zelf?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 03:07
farlane schreef op 06 december 2002 @ 21:35:
Wat is precies het probleem bij een 'delete this' dan ? ( Behalve dat je moet oppassen met eventuele referenties naar het 'this' object buiten het object zelf?
Het gaat tegen het principe in, dat de code die een object maakt, ook verantwoordelijk is voor het opruimen ervan. Deze verantwoordelijkheid kan doorgegeven worden aan andere stukken code, maar hoort uiteraard niet bij het object zelf uit te komen. Die zal zichzelf immers nooit wissen, omdat 'ie daarvoor moet weten dat niemand 'm meer gebruikt.

Aangezien 'ie zichzelf alleen kan wissen als reactie op een methode die door 'andere code' aangeroepen wordt, kan 'ie dat dus alleen doen in situaties waarin 'ie zeker weet dat er nog andere code met een referentie naar het object bestaat. Die code moet dan heel duidelijk weten dat die referentie daarna ongeldig is! Als die code dus schijnbaar de verantwoordelijkheid heeft om te zorgen dat de referentie niet meer gebruikt wordt, kan die code het object ook wel zelf deleten.

Een normaal object blijft geldig totdat iemand 'm delete. Als je hier aan tornt, bestaat er een zeer grote kans dat iemand een keer de fout maakt een methode aan te roepen op een ongeldige referentie.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Soultaker schreef op 06 December 2002 @ 21:46:
[...]
[ tegen delete this

Het gaat tegen het principe in, dat de code die een object maakt, ook verantwoordelijk is voor het opruimen ervan. Deze verantwoordelijkheid kan doorgegeven worden aan andere stukken code, maar hoort uiteraard niet bij het object zelf uit te komen. Die zal zichzelf immers nooit wissen, omdat 'ie daarvoor moet weten dat niemand 'm meer gebruikt.

Aangezien 'ie zichzelf alleen kan wissen als reactie op een methode die door 'andere code' aangeroepen wordt, kan 'ie dat dus alleen doen in situaties waarin 'ie zeker weet dat er nog andere code met een referentie naar het object bestaat. Die code moet dan heel duidelijk weten dat die referentie daarna ongeldig is! Als die code dus schijnbaar de verantwoordelijkheid heeft om te zorgen dat de referentie niet meer gebruikt wordt, kan die code het object ook wel zelf deleten.
In dit geval (object=window) is de aanroepende code feitelijk het OS, dat een window opruimt. Alleen kan Windows natuurlijk geen delete pWindow; doen (C++ specifiek), vandaar dat je een gewone functie-call uiteindelijk in een delete this resulteert. De implicatie van delete this is wel, dat je je owner op de hoogte moet stellen van je suicide. Misschien dat iemand met meer BCB ervaring kan uitleggen hoe de baseclasses van TForm een window-unregister doen bij het OS.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

Topicstarter
whoami schreef op 06 december 2002 @ 15:33:
Als je de form sluit, wordt het geheugen van die form vrijgegeven + het geheugen van de controls op die form.
Geheugen dat gealloceerd werd door eigen objecten enzo, moet je zelf nog vrijgeven.
Eigen objecten: zijn dat ook een willekeurig aantal tekstvelden die je in de onFormShow op je scherm laat toveren? Dat wil dus zeggen dat ik er niet aan moet zitten.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//---------------------------------------------------------------------------

#ifndef InvoerH
#define InvoeH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <DBGrids.hpp>
#include <ExtCtrls.hpp>
#include <Grids.hpp>
//---------------------------------------------------------------------------
class TForm6 : public TForm
{
__published:    // IDE-managed Components
        TDBGrid *DBGrid1;
        TPanel *Panel1;
        TLabel *Label1;
        TLabel *Label2;
        TEdit *Afkorting;
        TButton *Button1;
        TButton *Button2;
        TButton *Button3;
        TButton *Volgende;
        TButton *Laatste;
        TButton *Vorige;
        TButton *Eerste;
         void __fastcall Button3Click(TObject *Sender);
        void __fastcall FormShow(TObject *Sender);
        void __fastcall DBGrid1DrawColumnCell(TObject *Sender,
          const TRect &Rect, int DataCol, TColumn *Column,
          TGridDrawState State);
        void __fastcall EersteClick(TObject *Sender);
        void __fastcall LaatsteClick(TObject *Sender);
        void __fastcall VolgendeClick(TObject *Sender);
        void __fastcall VorigeClick(TObject *Sender);
        void __fastcall Button2Click(TObject *Sender);
        void __fastcall Button1Click(TObject *Sender);
private:    // User declarations
public:     // User declarations
DynamicArray<TEdit *> teksvelden;// de length var. wordt in een methode "gezet"

        __fastcall TForm6(TComponent* Owner);
        void __fastcall UpdateFields();
};
//---------------------------------------------------------------------------
extern PACKAGE TForm6 *Form6;
//---------------------------------------------------------------------------
#endif


Waar moet ik dan de destructor neerzeten? Om een Dynamic_array uit het geheugen te verwijderen, moet ik tekstvelden.Length=0; doen in de sestructor, maar waar zet ik die in mijn code dat precies neer?

Verwijderd

correct me if i'm wrong maar volgens mij is een delete this redelijk funest als het object op de stack staat ipv op de heap...

illustratie code :

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyObject
{
  public :
    MyObject ( ) { }
    void destroy ( ) { delete this; }
    ~MyObject ( ) { }
};

int main ( int argc , char **argv )
{
  MyObject obj;
  obj.destroy ( );
  return 0;
}

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 24-08 22:38
[Soultaker & Ankorahul vertellen waarom 'delete this' slecht is ]

Ik kan me voorstellen dat een implementatie een 'geheugenbeheer object' voor heap allocaties implementeert met bv ref counting.

Als dit object dan merkt dat ie niet meer gereferenced wordt, gooit hij zichzelf weg, en ruimt daarbij ook zijn geheugenblock op.

Ik moet zegen dat ik het zelf ook nog nooit nodig heb gehad, maar volgens mij is het ook niet per definitie een verkeerd iets.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • whoami
  • Registratie: December 2000
  • Laatst online: 21:36
Als de objecten op de stack staan, dan moet je ze afaik niet zelf vrijgeven mbhv delete.

https://fgheysels.github.io/


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Een "window" object staat normaal gesproken niet op de stack; dan zou het window verdwijnen als de functie retourneert. De uitzondering is natuurlijk een dialoog window (yes/no, en je gaat pas door als je een antwoord hebt)

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

farlane schreef op 06 december 2002 @ 21:35:
Wat is precies het probleem bij een 'delete this' dan ? ( Behalve dat je moet oppassen met eventuele referenties naar het 'this' object buiten het object zelf?
De verleiding is erg groot om later nog een member pointer of variabele toe te voegen of te deleten, of bijvoorbeeld zo'n constructie als dit:
C++:
1
2
3
4
5
6
7
8
9
10
bool MyClass::DestructIfReady()
{
if(m_Completed)
  {
  delete m_SubObject;
  delete this;
  }
// Return whether we were ready
return m_Completed ? true : false;     // KABOOM!!!!!
}

Dit zegt dus enorm knal :) Tis levensgevaarlijk spul om in een functie delete this te doen, en idd zoals Soultaker al zegt heeft een 'using class' geen idee dat z'n pointer ineens al of niet ongeldig is.

Het kan heel erg handig zijn, maar tis niet iets om in de 'beginner-fase' waar gang-ster zit mee te gaan stunten...

Professionele website nodig?


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 03:07
farlane schreef op 07 december 2002 @ 16:12:
Ik kan me voorstellen dat een implementatie een 'geheugenbeheer object' voor heap allocaties implementeert met bv ref counting.
Ik ben heel benieuwd hoe je dat dacht te implementeren?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

MSalters schreef op 07 December 2002 @ 00:03:
Misschien dat iemand met meer BCB ervaring kan uitleggen hoe de baseclasses van TForm een window-unregister doen bij het OS.
Okee :)

VCL is gebaseerd op het 'owner' principe, dwz. dat iedere class die van TComponent is afgeleid (zijnde alle visuele en non-visuele componente) in de constructor een 'TComponent* Owner' mee moet krijgen. Zodra een TComponent gedestruct wordt delete hij automatisch al zijn owned components.

Voordat je applicatie gestart wordt maakt de BCB-runtime 1 TComponent derivant voor je aan: een global TApplication instance genaamd Application. Alle autocreated forms hebben dit object als owner, en worden dus automatisch gedestruct bij het afsluiten van het programma. Een auto-create form (alle bij default) mag je dan ook alleen deleten als je zeker weet dat je 'm niet meer gaat gebruiken, maar over het algemeen (99,999% van de gevallen) kun je ze beter laten slingeren. Alleen als je echt dynamisch windows/controls gaat aanmaken zul je zelf moeten deleten, maar daar je over het algemeen dan nog parent gelijkstelt aan owner ben je dan alsnog met 1 delete meestal klaar.

Perfect systeem voor dit doel, en je hoeft maar 1 regel te onthouden totdat je in de 'Advanced' regionen komt: nooit iets van VCL deleten :)

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

farlane schreef op 07 december 2002 @ 16:12:
Ik kan me voorstellen dat een implementatie een 'geheugenbeheer object' voor heap allocaties implementeert met bv ref counting.

Als dit object dan merkt dat ie niet meer gereferenced wordt, gooit hij zichzelf weg, en ruimt daarbij ook zijn geheugenblock op.

Ik moet zegen dat ik het zelf ook nog nooit nodig heb gehad, maar volgens mij is het ook niet per definitie een verkeerd iets.
De enige plek waar ik ooit delete this heb gebruikt is idd in de 'DecreaseReference' functie van framework base classes :) En daar het een 'advanced topic' is om dat zelf te implementeren, gaan we daar dus gang-ster niet mee lastig vallen zoals ik al zei :Y)

Professionele website nodig?


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 03:07
curry684 schreef op 07 December 2002 @ 22:02:
De enige plek waar ik ooit delete this heb gebruikt is idd in de 'DecreaseReference' functie van framework base classes :) En daar het een 'advanced topic' is om dat zelf te implementeren, gaan we daar dus gang-ster niet mee lastig vallen zoals ik al zei :Y)
Regel dat dan met een proxy die je op de stack alloceert, zou ik zeggen. Is een stuk veiliger (al heb je dan misschien wat overbodige add/decrease reference functies). Het nut van reference counting is sowieso nogal beperkt als je zelf moet onthouden wat je referenced/dereferenced, maar goed, in sommige situaties is het een uitkomst.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Soultaker schreef op 07 december 2002 @ 22:31:
Regel dat dan met een proxy die je op de stack alloceert, zou ik zeggen. Is een stuk veiliger (al heb je dan misschien wat overbodige add/decrease reference functies). Het nut van reference counting is sowieso nogal beperkt als je zelf moet onthouden wat je referenced/dereferenced, maar goed, in sommige situaties is het een uitkomst.
Ikke u compleet niet snap? :?

[edit]
Na 5 minuten staren denk ik dat ik je wel begrijp: je bedoelt dat COM kut is... maja daar is bijna heel de wereld al achter (zie m'n sig ;) ).

Want in COM idd moet je in principe handmatig AddRef en Release doen, maar ik heb altijd alleen maar met 'Reference Classes' op de stack gewerkt (ik mislas proxy ook even). Punt waaraan ik refereerde was echter dat je zo'n 'proxy' op 2 manieren kunt implementeren.

Manier 1:
C++:
1
2
3
4
5
6
7
8
9
10
MyReferenceProxy::~MyReferenceProxy()
{
if(m_ReferencedClass && m_ReferencedClass->DecreaseReference() == 0)
  delete m_ReferencedClass;
}

int ReferencedClass::DecreaseReference()
{
return --m_ReferenceCount;
}

Manier 2:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MyReferenceProxy::~MyReferenceProxy()
{
if(m_ReferencedClass)
  m_ReferencedClass->DecreaseReference();
}

int ReferencedClass::DecreaseReference()
{
if(!--m_ReferenceCount)
  {
  delete this;
  return 0;       // <---- Hier doelde ik een stuk hierboven op!!!
  }
return m_ReferenceCount;
}

[ Voor 52% gewijzigd door curry684 op 07-12-2002 22:42 . Reden: Langs mekaar praten :) ]

Professionele website nodig?


Verwijderd

Topicstarter
Verwijderd schreef op 07 December 2002 @ 12:00:
[...]

Eigen objecten: zijn dat ook een willekeurig aantal tekstvelden die je in de onFormShow op je scherm laat toveren? Dat wil dus zeggen dat ik er niet aan moet zitten.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//---------------------------------------------------------------------------

#ifndef InvoerH
#define InvoeH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <DBGrids.hpp>
#include <ExtCtrls.hpp>
#include <Grids.hpp>
//---------------------------------------------------------------------------
class TForm6 : public TForm
{
__published:    // IDE-managed Components
        TDBGrid *DBGrid1;
        TPanel *Panel1;
        TLabel *Label1;
        TLabel *Label2;
        TEdit *Afkorting;
        TButton *Button1;
        TButton *Button2;
        TButton *Button3;
        TButton *Volgende;
        TButton *Laatste;
        TButton *Vorige;
        TButton *Eerste;
         void __fastcall Button3Click(TObject *Sender);
        void __fastcall FormShow(TObject *Sender);
        void __fastcall DBGrid1DrawColumnCell(TObject *Sender,
          const TRect &Rect, int DataCol, TColumn *Column,
          TGridDrawState State);
        void __fastcall EersteClick(TObject *Sender);
        void __fastcall LaatsteClick(TObject *Sender);
        void __fastcall VolgendeClick(TObject *Sender);
        void __fastcall VorigeClick(TObject *Sender);
        void __fastcall Button2Click(TObject *Sender);
        void __fastcall Button1Click(TObject *Sender);
private:    // User declarations
public:     // User declarations
DynamicArray<TEdit *> teksvelden;// de length var. wordt in een methode "gezet"

        __fastcall TForm6(TComponent* Owner);
        void __fastcall UpdateFields();
};
//---------------------------------------------------------------------------
extern PACKAGE TForm6 *Form6;
//---------------------------------------------------------------------------
#endif


Waar moet ik dan de destructor neerzeten? Om een Dynamic_array uit het geheugen te verwijderen, moet ik tekstvelden.Length=0; doen in de destructor, maar waar zet ik die in mijn code dat precies neer?
Uhm, misschien een domme opmerking: maar hebben jullie al antwoord gegeven op mijn concrete vraag?

Dit is wat ik er tot nu toe van begrijp: Van alle auto-generated windows moet ik afblijven en ik dacht in de laatste opmerking te horen dat controls die aan een autogenerated window worden toegevoegd, dezelfde owner hebben en bij het afsluiten van dat Form ook worden verwijderd, maar dat moest ik dan toch maar weer deleten. (Voorstaande is beetje wartaal, en zo begrijp ik het ook). Een antwoord met je moet het zetten van die array op length 0 daar neerzetten, omdat ...... is echt genoeg en dan voor het willekeurig aantal tekstvelden een soortgelijke uitleg.

Nog een keer voor de duidelijkheid de algemene structuur:

De dynamische array wordt aangemaakt in de headerfile die ik hierboven al heb staan.

In een methode die wordt aangeroepen als je klikt op een Button:
C++:
1
2
3
4
5
6
7
8
9
10
11
tekstveld.Length=aantal;

for (int i=0;i<aantal;i++){
        //maak een textveld aan
        tekstveld[i] = new TEdit(Panel1);
        tekstveld[i]->Parent = Panel1;
        tekstveld[i]->Visible = true;
//enz andere properties
}

Het doel van dit alles is dat ik geen memoryleaks wil hebben en bij gebruikers geen blauwe schermen en Runtime errors genereer. Bovendien vind ik het interessant om te weten, wat er nu eigenlijk echt gebeurt, maar dat is in principe bijzaak.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Je zet de Owner van die tekstvelden op Panel1. Als Panel1 vrijgegeven wordt, geeft ie automatisch al zn kinderen ook vrij. Je hoeft dus in dit geval niets te doen.

Als je geen Owner mee (kan) geven moet je wel alles wat je creeerd deleten.

Alles wat BCB creeerd voor jouw hoef je niet vrij te geven.

PS: Zet ook eens die memory leak detector aan die in BCB 5 en hoger zit...

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Topicstarter
En de Dynamic Array dan?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Die is van jezelf dus moet je deleten. Alles wat van TComponent is afgeleid en/of door de IDE is gemaakt moet je niet deleten, al het andere wel.

(tip: als je F1 doet op een classname staat er altijd een link 'Hierarchy', na 5 keer klikken daarop heb je de basisprincipes van de VCL-structuur wel door)

Professionele website nodig?


Verwijderd

Topicstarter
Maar waar kan ik dat dan doen? Ik kan het niet in de destructor zetten van de TForm6 class. Waar dan wel?

  • whoami
  • Registratie: December 2000
  • Laatst online: 21:36
In de Form-close.
(Waarom kan je het niet in de destructor zetten?)

https://fgheysels.github.io/


Verwijderd

Topicstarter
Omdat ik niet weet waar die destructor gedefinieerd staat. In al die mooie C++ boeken gaan ze uit van zelf gedefinieerde objecten en niet van BC6 objecten. Voor mijn eigen classes zou ik het denk ik wel begrijpen.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

?!?

Je copy/paste je hele header hier maar weet vervolgens niet waar je een destructor zou moeten toevoegen, maar je zou het in een eigen class wel kunnen? :?

* curry684 is de draad kwijt...

Professionele website nodig?


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

een destructor is een destructor. BCB objecten zijn gewone objecten.

klassenaam(); // constructor
~klassenaam(); // destructor

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Topicstarter
Maar als ik alleen neerzet: ~TForm6 (){
tekstvelden.Length=0;
}
Dan lijkt het me dat het Form zelf met alle controls erbij, niet worden verwijderd. M.a.w. ik denk dat ik de destructor van de VCL overschrijf. Please correct me, if I am wrong...

  • whoami
  • Registratie: December 2000
  • Laatst online: 21:36
Dat zou wel eens kunnen zijn.... ;)

Jouw form (TForm6) inherit van TForm. Je zult dus de destructor van TForm ook moeten aanroepen.

Hoe doe je dat ook alweer in C++ ....
code:
1
2
3
~TForm6() : TForm()
{
}

ofzo....
* whoami weet het nie meer zeker.

https://fgheysels.github.io/


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Erm nee. TObject introduceert een virtual destructor, waardoor alle afgeleide classes per definitie een virtual destructor hebben: ergo alle destructors worden automatisch in de correct volgorde aangeroepen. Sterker nog: je MAG de base class destructor niet aanroepen...

En voor gang-ster: BCB doet geen vieze dingen die niet in je header staan. Als er geen destructor gedefinieerd is, bestaat ie niet. Punt. :)

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

LordLarry schreef op 09 december 2002 @ 15:42:
een destructor is een destructor. BCB objecten zijn gewone objecten.

klassenaam(); // constructor
~klassenaam(); // destructor
Ondanks dat ie het per definitie is zoals ik hierboven schreef is het een goede gewoonte om virtual te schrijven voor iedere destructor die je maakt.

Professionele website nodig?


Verwijderd

Topicstarter
Mijn klassenaam is zoals in de header te lezen was: TForm6. Volgens ~klassenaam zou ~TForm6(); moeten werken. Dit werkt alleen niet.

Als ik ~TForm6(); binnen de classdefinitie zet, zoals in mijn C++ boek, krijg ik de error Tform6 confilcts with baseclass Tform.

Als ik ~TForm6(); onder de classdefinitie zet, niet zoals in mijn C++ boek, krijg ik de error Destructor name must match classname.
De classname is TForm6, zoals te verifieren valt in de header, heeft dat public er soms iets mee te maken?

Verwijderd

Topicstarter
/me Kicks ass

  • whoami
  • Registratie: December 2000
  • Laatst online: 21:36
Niet moeilijk doen en zet het gewoon in de OnClose van de Form.

https://fgheysels.github.io/


Verwijderd

Topicstarter
Ook goed, the story ends here.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Verwijderd schreef op 09 december 2002 @ 15:53:
Maar als ik alleen neerzet: ~TForm6 (){
tekstvelden.Length=0;
}
Dan lijkt het me dat het Form zelf met alle controls erbij, niet worden verwijderd. M.a.w. ik denk dat ik de destructor van de VCL overschrijf. Please correct me, if I am wrong...
Ok, bij deze dan. Je eigen dtor runt voordat je member dtors runnen, en voordat de base class dtor runt. Dat betekent dat de "tekstvelden" dtor wel runt. Als deze zelf z'n resources niet opruimt, dan moet je handmatig de resources opruimen.

Dit is een verschil met de copy constructor, die je wèl kunt vervangen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

MSalters schreef op 11 December 2002 @ 20:26:
Ok, bij deze dan. Je eigen dtor runt voordat je member dtors runnen, en voordat de base class dtor runt. Dat betekent dat de "tekstvelden" dtor wel runt. Als deze zelf z'n resources niet opruimt, dan moet je handmatig de resources opruimen.

Dit is een verschil met de copy constructor, die je wèl kunt vervangen.
En tevens belangrijk detail: je kunt maar 1 destructor hebben per class. Daar TForm6 je eigen custom afgeleide class is van TForm kun je daar dus in modderen wat je wil. VCL schrijft alleen een constructor voor omdat je daarin een TComponent* Owner moet meegeven.

Daarnaast gaat het verhaal van MSalters wederom alleen geheel op voor virtual destructors :P

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Nee hoor, ook een non-virtual dtor roept z'n parent aan. Het enige effect van virtual is dat delete pointer_to_Base; wel een virtual derived dtor aanroept, maar geen non-virtual dtors.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 03:07
MSalters schreef op 12 december 2002 @ 00:01:Het enige effect van virtual is dat delete pointer_to_Base; wel een virtual derived dtor aanroept, maar geen non-virtual dtors.
Exact zoals alle andere member functions, om het maar even samen te vatten.

  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

Je kunt in een dtor geen delete this; neerzetten, omdat je dan een dikke deadlock krijgt. delete this; roept nl. de dtor van het object aan, die weer de dtor van het object aanroept, enzovoort... Tenzij je virtual dtors gebruikt (waarbij je code al na de eerste iteratie crasht) zal je code hangen.

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?

Pagina: 1