Toon posts:

[C++] pointer deleten en dan opnieuw allocaten*

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hier de code:
code:
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
#include <stdio.h>
#include <iostream.h>
#include <windows.h>
#include <stdlib.h>

class cBaseTile
{
public:
int TileFunct();
};

class cSpecialTile : public cBaseTile
{
public:
int TileFunct();
};

int cBaseTile::TileFunct()
{
cout<<"Testing, base tile.\n";
}

int cSpecialTile::TileFunct()
{
cout<<"Testing, special tile.\n";
}



int main()
{

cBaseTile *mMyWorld[10][10];
delete mMyWorld[2][2];
mMyWorld[2][2] = new cSpecialTile;


mMyWorld[1][1]->TileFunct();
mMyWorld[2][2]->TileFunct();

Er worden dus 2 classes gemaakt die bijde een functie hebben. Nu heb ik een pointer gemaakt die naar cBaseTile point en dus "base tile" afdrukt. Maar bij mMyWorld[2][2] wil ik een uitzondering maken en hem wat anders laten doen. Dus ik delete mMyWorld[2][2] en allocate hem naar CSpecialTile pointen. Maar het programma drukt dus wel 2x "base tile" af. mMyWorld[2][2] point dus wel gewoon naar cBaseTile en cBaseTile.TileFunct() wordt gerunt. Delele ik hem niet goed?

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 02:22
Tip: "virtual"

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: 04-09 14:38

curry684

left part of the evil twins

Op dinsdag 26 maart 2002 10:41 schreef Dobie het volgende:
code:
1
2
3
4
5
int main()
{
cBaseTile *mMyWorld[10][10];
delete mMyWorld[2][2];
...
Hmmm ik weet niet wat je hiermee van plan bent maar dit gaat op releasebuild met enorme access violations of segfaults komen hoor... in debugbuild kom je er nog wel ff mee weg. Je zult wel tactisch wat code weggelaten hebben :7

Ennuh, je roept twee keer op een cBaseTile* de functie TileFunct aan, dan is het toch logisch dat 2 keer de functie cBaseTile::TileFunct wordt aangeroepen? (8>

(tip: virtual ;) )

Professionele website nodig?


Verwijderd

Topicstarter
Waarom dit voor problemen gaat zorgen snap ik niet.

Het is dus de bedoeling dat mMyWorld[2][2] niet meer naar cBaseTile maar naar cSpecialTile gaat pointen. En van virtuele zooi weet ik nog niets dus dat doet geen belletje rinkelen.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op dinsdag 26 maart 2002 11:15 schreef Dobie het volgende:
Waarom dit voor problemen gaat zorgen snap ik niet.
Uhhhhhh als je daar geen code weggelaten hebt kan het niet eens werken...
Het is dus de bedoeling dat mMyWorld[2][2] niet meer naar cBaseTile maar naar cSpecialTile gaat pointen. En van virtuele zooi weet ik nog niets dus dat doet geen belletje rinkelen.
Okee wat ik dus bedoelde: je blijft die functie aanroepen op een cBaseTile pointer. Oftewel de compiler heeft zoiets van dat ie dan de TileFunct implementatie van cBaseTile aan moet roepen.

Op runtime echter is het door RunTime Type Info (RTTI) mogelijk te achterhalen dat die cBaseTile pointer wijst naar een class van het type cSpecialTile, echter deze achterhaalactie kost kruim en wordt dus alleen uitgevoerd als jij daar specifiek om vraagt door de functie virtual te maken.

Zodra je 1 keer in een hierarchie een functie virtual hebt gemaakt zijn alle overloads in derived classes automatisch medevirtual, en wordt er op compiletijd ingebouwd dat er op runtime wordt gekeken naar het feitelijke type van de class ipv alleen naar de pointer. De volgende wijziging van je code doet het dus wel goed:
code:
1
2
3
4
5
6
7
8
9
10
11
class cBaseTile
{
public:
  virtual int TileFunct();
};

class cSpecialTile : public cBaseTile
{
public:
  virtual int TileFunct();
};

De virtual in cSpecialTile is optioneel omdat de functie dankzij cBaseTile al virtual is, maar verduidelijkt de zaak wel.

Was dit enigszins te volgen? Zo nee: Google power

Professionele website nodig?


Verwijderd

Topicstarter
Als ik de functies virtueel maak crasht het programma gelijk door een geheugenfout.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Ieps even mezelf citeren:
Uhhhhhh als je daar geen code weggelaten hebt kan het niet eens werken...
Herstel, dit gaat STOMTOEVALLIG goed omdat je geen membervariabelen gebruikt en de code toevallig aanwezig is, maar dit is LEVENSGEVAARLIJK. Ik zal de hele code maar ff fixen voor je:
code:
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
#include <stdio.h>
#include <iostream.h>
#include <windows.h>
#include <stdlib.h>

const int    c_Dimensions = 10;

class cBaseTile
{
public:
  virtual int TileFunct()
    {
    cout << "Testing, base tile.\n";
    }
};

class cSpecialTile : public cBaseTile
{
public:
  virtual int TileFunct()
    {
    cout << "Testing, special tile.\n";
    }
};

int main()
{
cBaseTile*   l_MyWorld[c_Dimensions][c_Dimensions];
int     l_X;
int     l_Y;

// Fill the array with objects
for(l_X = 0; l_X != c_Dimensions; l_X++)
  for(l_Y = 0; l_Y != c_Dimensions; l_Y++)
    l_MyWorld[l_X][l_Y] = new cBaseTile;

// Delete one and replace it with a special tile
delete l_MyWorld[2][2];
l_MyWorld[2][2] = new cSpecialTile;

// Print contents of tiles (1,1) and (2,2)
l_MyWorld[1][1]->TileFunct();
l_MyWorld[2][2]->TileFunct();

// Delete all tiles
for(l_X = 0; l_X != c_Dimensions; l_X++)
  for(l_Y = 0; l_Y != c_Dimensions; l_Y++)
    delete l_MyWorld[l_X][l_Y];
}

Aub goed doorlezen en doorgronden voordat je verder vraagt, en run het eens een keer (ik hoop dat het compilet daar het hier uit Notepad komt ;) )

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op dinsdag 26 maart 2002 12:02 schreef Dobie het volgende:
Als ik de functies virtueel maak crasht het programma gelijk door een geheugenfout.
Hahaha klopt precies door wat ik in mijn vorige post zei: je gebruikte geen membervariabelen en dus ging het stomtoevallig goed, maar zodra je RTTI gebruikt wordt er in de class een 'virtual function table' oftewel vtable aangemaakt, en daar je de classes niet feitelijk aangemaakt hebt krijg je dus nu wel access violations :)

Professionele website nodig?


Verwijderd

Topicstarter
Ja het werkt. Je moet dus iedere pointer apart allocaten?

Bedankt in ieder geval.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op dinsdag 26 maart 2002 12:13 schreef Dobie het volgende:
Ja het werkt. Je moet dus iedere pointer apart allocaten?
NEEEEE!!! :)

Een pointer wijst naar een instance! Dus je allocate alle INSTANCES, en wijst je array van pointers er vervolgens naar zodat je ze terug kan vinden. Vergelijk:
code:
1
2
3
4
5
cBaseTile    l_StaticInstance;
cBaseTile*   l_Pointer = &l_StaticInstance;

l_StaticInstance.TileFunct();
l_Pointer->TileFunct();

Eerst alloceer ik hier een class op de stack, en vervolgens pak ik het geheugenadres daarvan wat ik in een pointer opsla. Een pointer is dan ook niets anders dan een geheugenadres, en heeft niets van doen met waar hij feitelijk naar wijst.
Bedankt in ieder geval.
No prob, dit is tricky spul om te leren dan ben ik altijd wel bereid iets meer te typen ;)

Professionele website nodig?


Verwijderd

Topicstarter
Zeker als het de eerste keer is dat je pointers gebruikt.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 02:22
Op dinsdag 26 maart 2002 12:13 schreef Dobie het volgende:
Ja het werkt. Je moet dus iedere pointer apart allocaten?

Bedankt in ieder geval.
Nee, dat hoeft ook weer niet altijd. Je kunt bv. ook 99
base objecten maken met std::vector<BaseTile>(99), en de
99 pointers daar naar laten wijzen.
Het probleem met "raw" pointers is wel of geen ownership; wat moet je met zo'n pointer doen als je 'em niet meer nodig hebt? In jouw geval denk ik dat de pointers "owning" moeten zijn, dus dat het wel verstandig is om de pointers allemaal te allocated; dan mag je er nl. een deleten en 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

Pagina: 1