[c++] class met variabel aantal onderliggende members

Pagina: 1
Acties:

  • BdR
  • Registratie: Juni 2001
  • Laatst online: 03-09-2025

BdR

TV is gooder then books

Topicstarter
het zal wel een n00b vraag zijn, maar ik kon er niets over vinden dus, here goes..

Ik ben bezig met een C++ programmaatje die lijnen opslaat, inleest en weergeeft. Is vrij simpel maar ik breid het later nog wel uit. Dus ik heb eerst de volgende classes aangemaakt.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class TCoordinate {
  int x;
  int y;
};

class TMyLine {
  TCoordinate Coords[10];
};

class TMyDrawing {
private:
  TMyLine Lines[10];
public:
  bool ReadFile(string filename);
  bool WriteFile(string filename);
};

probleem is nu dat een lijn slechts 10 coordinaten kan bevatten. Dat moet niet via een constante 10 of 20 of whatever. Ik wil tussen de 0 en oneindig coordinaten hebben. Net zo wil ik geen limiet hebben aan het aantal lijnen in een tekening.

Hoe kan ik dat het beste doen? met pointers ofzo? :? maar hoe maakt je bij het aanmaken van een class TMyDrawing een TMyLine array van varabele grootte aan?

mijn web games -> Impossible Snake 2 :: Impossible Snake :: Snake Slider


  • Icelus
  • Registratie: Januari 2004
  • Niet online
Ja, dat kan door gebruik te maken van een container.
De STL (Standard Template Library) bevat een aantal veelgebruikte containers zoals vector en linked-lists.

De STL is erg uitgebreid; uitleg van STL:
http://www.codeproject.org/vcpp/stl
http://www.mindcracker.com/mindcracker/c_cafe/stl/stlt1.asp
http://www.sgi.com/tech/stl

[ Voor 3% gewijzigd door Icelus op 21-10-2004 23:17 ]

Developer Accused Of Unreadable Code Refuses To Comment


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Die TMyCoordinate gaat natuurlijk niet werken, welke public members heeft die nou?
offtopic:
En die T... prefix is ook niet nodig, al helemaal niet als je ook My... als prefix gebruikt. Borland heeft die nog om historische redenen, maar tegenwoordig gebruik je daar namespaces voor.

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


  • BdR
  • Registratie: Juni 2001
  • Laatst online: 03-09-2025

BdR

TV is gooder then books

Topicstarter
idd geen public members, maar het ging eerst even om het idee.

Maar met die STL containers, kan je daar ook custom classes in opslaan? dus..
code:
1
2
3
4
TMyLine OneLine;
vector<TMyLine> Lines;
// lijn inlezen
Lines.insert(Lines.begin(), OneLine);

kheb hier ff geen C++ compiler

mijn web games -> Impossible Snake 2 :: Impossible Snake :: Snake Slider


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:32

.oisyn

Moderator Devschuur®

Demotivational Speaker

In C++ is er geen verschil tussen "custom" classes en niet-"custom" classes (whatever that may be). Je kunt er dus elk type invrotten waar gewone normale copy semantics voor zijn gedefinieerd (zoals een al dan niet default copy constructor en operator = e.d.)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • BdR
  • Registratie: Juni 2001
  • Laatst online: 03-09-2025

BdR

TV is gooder then books

Topicstarter
code:
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdlib>

class TPart {
public:
  int x;
  int y;
};

class TSnakeStored {
public:
  vector<TPart> Parts;
};

Dit stukje code geeft op regel 9 een error "Type name expected" :? Ik heb toch <TPart> aangegeven? Ik werk trouwens met Borland C++ Builder. zelfs "vector<int> Parts;" geeft hetzelfde foutmelding.. :?

edit:
ach ik heb het al... "#include <vector.h>" vergeten :)

[ Voor 18% gewijzigd door BdR op 22-10-2004 22:43 ]

mijn web games -> Impossible Snake 2 :: Impossible Snake :: Snake Slider


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:32

.oisyn

Moderator Devschuur®

Demotivational Speaker

het is #include <vector>, vector.h is deprecated ;)
Dan staat vector bovendien in de std namespace, dus moet je std::vector gebruiken, of iets als using std::vector doen

.edit @ _piranha_: ik weet 't O-)

[ Voor 10% gewijzigd door .oisyn op 23-10-2004 00:18 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

BdR schreef op 22 oktober 2004 @ 22:36:
ach ik heb het al... "#include <vector.h>" vergeten :)
#include <vector> doen; da's beter :)

[edit]
.oisyn : ja, je bent vervelend ;) :P

[ Voor 20% gewijzigd door Verwijderd op 22-10-2004 23:58 ]


  • BdR
  • Registratie: Juni 2001
  • Laatst online: 03-09-2025

BdR

TV is gooder then books

Topicstarter
ik snap die vectors nog niet helemaal.. stel ik heb nu dit
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
// stel een file met 3 opgeslagen TMyLines
// header geeft steeds aan hoeveel coords volgen
// 3  2,3  4,5  3,7
// 4  5,2  1,2  4,9  7,7
// 2  2,6  3,7

void TMyLine::read(istream& i) {

  byte xpos, ypos;
  TCoordinate Coordinate;

  i >> count; // how many coordinates

  while (count > 0) {
    // read byte, each byte contains grid position
    i >> xpos;
    i >> ypos;

    Coordinate = new TCoordinate;

    Coordinate.x = xpos;
    Coordinate.y = ypos;

    // add to line
    Parts.push_back(Coordinate);

    // countdown
    count = count - 1;
  }
}

istream& operator>>(istream& i, TMyLine & l) {
  l.read(i);
  return i;
}

dus ik kan TMyLines inlezen met de operator >> dus

inputfile >> Line

dan wordt er op regel 19 TCoordinates aangemaakt met new. Maar waar worden die nou weer de-delete ? Of moet ik die zelf in de destructor van de TMyLine deleten.. :?

mijn web games -> Impossible Snake 2 :: Impossible Snake :: Snake Slider


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:32

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik vind het een beetje vaag dat dat überhaupt werkt... Je Coordinate is helemaal geen pointer, dus ik vraag me af hoe de assignment van een pointer ervan kan werken.

Je kunt er ook gewoon voor kiezen om ze in de vector zelf op te slaan, dus die regel met new gewoon weghalen.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Sebazztiaan
  • Registratie: Februari 2002
  • Laatst online: 21-04 16:53

Sebazztiaan

sebas!

Mijn c++ code is wat weggezakt, maar ik denk dat je met dit voorbeeldje wel wat kan, heb het net snel in elkaar gezet.

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class MyLine
{
   vector <TCoordinate> _coordVec;

   public MyLine()
   {}

   public void MyLine::AddElement(TCoordinate tcoord)
   {
      _coordVec.push_back(tcoord);
   }

   public bool MyLine::DeleteElement(TCoordinate tcoord)
   {
      for(int i = 0; i < _coordVec.Size ; i++)
      {
         if(_coordVec.elementAt(i) == tcoord)
         {
            return true;
         }
      }
      return false;
   }

   public vector<TCoordinate> MyLine::GetVector()
   {
      return _coordVec;
   }
}

class TCoordinate
{
   byte _btXpos, _btYPos;
   

   getters en setters;
}

class TestClass
{
   MyLine* _myLine;
   
   public TestClass()
   {
      _myLine = new MyLine();
      FooAdd();
      ShowFoo();
   }

   public void TestClass::FooAdd()
   {
      //add een meuk elements;
      TCoordinate tc = new TCoordinate(xpos, ypos);
      _myLine->AddElement(tc)
   }

   public void TestClass::ShowFoo()
   {
      vector coords = _myLine->GetVector();
      //draw line from
      for(int i = 0; i < coords.size() ; i++)
      {
        TCoordinate toDrawFrom = coord.getElementAt(i);
        TCoordinate toDrawTo = coord.getElemantAt(i+1);
        
        //pseudo
        drawline(toDrawFrom.X, toDrawFrom.Y, toDrawTo.X, toDrawTo.Y);
      }       
   }
}


Oh ja, alles wat je dynamisch maakt, met new moet je zelf opruimen in je destructor he....

[ Voor 4% gewijzigd door Sebazztiaan op 26-10-2004 23:57 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:32

.oisyn

Moderator Devschuur®

Demotivational Speaker

Compileert dat überhaupt wel :? Of heb je die code gewoon even uit je mouw geschud?

Je schrijft class met een hoofdletter, je assignt nog steeds pointers aan non-pointers (een pointer declareer je met T * variabele, wat je niet doet, en new retourneert een pointer naar het object), je benadert non-pointers als pointers (je gebruikt -> ipv .), etc.

Ik stel voor je code voortaan even te compilen voordat je het online zet

[ Voor 68% gewijzigd door .oisyn op 26-10-2004 21:38 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Sebazztiaan
  • Registratie: Februari 2002
  • Laatst online: 21-04 16:53

Sebazztiaan

sebas!

Het was helemaal niet de bedoeling of het wel of niet compiled.... het was even om aan te geven hoe hij het zou kunnen implementeren, en ik had echt geen zin om het helemaal te testen.

En ja.. ik heb het even uit mijn mouw geschud, puur zodat hij een idee zou krijgen hoe het kan. Ik bedoel een code request... die kan hij op internet wel vinden toch...


En ja... win32 of c++ in dit geval is lang geleden..... :) it's java en C# all the way....

[ Voor 12% gewijzigd door Sebazztiaan op 26-10-2004 23:46 ]


  • BdR
  • Registratie: Juni 2001
  • Laatst online: 03-09-2025

BdR

TV is gooder then books

Topicstarter
Even ter verduidelijking, ik wil dus het volgende bijhouden.

- Er zijn een aantal tekeningen
- Elke tekening bestaat uit 1 of meer lijnen
- Elke lijn bestaat uit 1 of meer coordinaten

Dus je moet je zo'n soort boomstructuur voorstellen..
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
MyDrawing1
    |
    +-MyLines1
    |    |
    |    +- MyCoordinate1
    |    +- MyCoordinate2
    |
    +-MyLines2
         |
         +- MyCoordinate3
         +- MyCoordinate4
         +- MyCoordinate5

MyDrawing2
    |
    +-MyLines3
         |
         +- MyCoordinate6
         +- MyCoordinate7

mijn web games -> Impossible Snake 2 :: Impossible Snake :: Snake Slider


  • BdR
  • Registratie: Juni 2001
  • Laatst online: 03-09-2025

BdR

TV is gooder then books

Topicstarter
En ik heb het volgende stuk code. Het klopt allemaal, er zijn geen compiler errors oid. Alle members e.d. zijn public, zo kan voor het gemak alle GET en SET achterwege gelaten worden. Zo blijft deze voorbeeld code wat overzichtelijker.
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
50
51
52
53
class MyCoordinate
{
public:
   // members
   byte _Xpos, _Ypos;
   // constructor
   MyCoordinate(int x, int y) : _Xpos(x), _Ypos(y) {};
};

class MyLine
{
public:
   // members, 1 of meer coordinaten
   vector<MyCoordinate> _Coordinates;

   // constructor
   MyLine() {};
   // destructor
   ~MyLine() {
     // delete all coordinates
     vector<MyCoordinate>::iterator ic;
     while ( ( ic = _Coordinates.begin() ) != _Coordinates.end() ) {
       _Coordinates.erase( ic++ );
     }
   }
};

class MyDrawing
{
public:
   // members, 1 of meer lijnen
   vector<MyLine> _MyLines;
   // constructor, test initialise
   MyDrawing() {
      //create test line
      MyLine *Line = new MyLine;

      //create test coords
      MyCoordinate *tcoord = new MyCoordinate(4, 5);
      Line->_Coordinates.push_back(*tcoord);

      tcoord = new MyCoordinate(6, 7);
      Line->_Coordinates.push_back(*tcoord);
   };
   // constructor,
   ~MyDrawing() {
     // delete all lines
     vector<MyLine>::iterator il;
     while ( ( il = _MyLines.begin() ) != _MyLines.end() ) {
       _MyLines.erase( il++ );
     }
   }
};

mijn web games -> Impossible Snake 2 :: Impossible Snake :: Snake Slider


  • BdR
  • Registratie: Juni 2001
  • Laatst online: 03-09-2025

BdR

TV is gooder then books

Topicstarter
en nu de hamvraag, waar het mij allemaal om te doen is:

Hoe kan je deze "boomstructuur" nu makkelijk manipuleren? :?

Als ik bijvoorbeeld alles probeer af te drukken, met het volgende
code:
1
2
3
4
5
6
7
8
  MyDrawing *Drawing = new MyDrawing;
  vector<MyLine>::iterator il;
  while ( ( il = Drawing->_MyLines.begin() ) != Drawing->_MyLines.end() ) {
    vector<MyCoordinate>::iterator ic;
    while ( ( ic = Drawing->_MyLines[il]->_Coordinates.begin() ) != Drawing->_MyLines[il]->_Coordinates.end() ) {
      // doe bijv. iets met Drawing->_MyLines[il]->_Coordinates[ic].XPos;
    }
  }

krijg ik error 'Operator+' not implemented in type 'vector<MyLine, allocator<MyLine>>' for arguments of type 'MyLine *' op regel 5 na de eerste "_MyLines[il]" :? ik gebruik toch helemaal geen plus teken? :?

mijn web games -> Impossible Snake 2 :: Impossible Snake :: Snake Slider


  • Domokoen
  • Registratie: Januari 2003
  • Laatst online: 14:26
Is er nu ook nog een vraag over :?
Want deze code lijkt mij de oplossing van je oorspronkelijke probleem en je beschrijft geen nieuwe. Of was dit om ff te laten zien hoe je het uiteindelijk hebt opgelost?

edit:

en toen verscheen de post hierboven ook nog...
Kan je misschien alles in één post zetten ipv op jezelf lopen te replyen?

[ontopic]
uhm, ik vind je while lus een beetje dodgy. Ik werk zelf altijd zo met iterators:
code:
1
2
3
for(iter = vec.begin(); iter != vec.end(); iter++) {
  doe dingen met (*iter)
}

Maar bij jou mis ik het verhogen van de iterator. Sowieso is die code in van de while lus erg onleesbaar...
Dus zoiets zou wnl wel werken:
code:
1
2
3
for(vector<MyLine>::iterator il = Drawing->_MyLines.begin(); il != Drawing->_MyLines.end(); il++) {
 blah blah
}

En nog meer edits: jouw vectoren bevatten géén pointers, dus waarom gebruik je dan de -> dereference operator? Je moet de . gebruiken, maar nog beter zou zijn om vector<MyLine*> te gebruiken dan heb je geen class copying en andere overhead.
[/ontopic]

[ Voor 79% gewijzigd door Domokoen op 07-11-2004 15:21 ]


  • BdR
  • Registratie: Juni 2001
  • Laatst online: 03-09-2025

BdR

TV is gooder then books

Topicstarter
Ok thanks voor de aanwijzingen :) alle vectoren bevatten nu pointers, en ik heb nu een FOR ipv WHILE.
code:
1
2
3
4
5
for(vector<MyLine*>::iterator il = Drawing->_MyLines.begin(); il != Drawing->_MyLines.end(); il++) {
  for(vector<MyCoordinate*>::iterator ic = Drawing->_MyLines[il]->_Coordinates.begin(); ic != Drawing->_MyLines[il]->_Coordinates.end(); ic++) {
    // doe bijv. iets met Drawing->_MyLines[il]->_Coordinates[ic].XPos;
  }
}

Maar hij geeft nog steeds dezelfde foutmelding hier op regel 2 bij die eerste "_MyLines[il]". Het is trouwens qua (on)leesbaarbaarheid nog ongeveer hetzelfde gebeleven vind ik..

mijn web games -> Impossible Snake 2 :: Impossible Snake :: Snake Slider


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
il is een iterator, geen index. il wijst vanaf het begin naar MyLines. Je moet dus ook verder niet MyLines[il] schrijven, maar simpelwel *il of il->

En vermijd het gebruik van pointers, die zijn vaak niet nodig. Je code 3 posts omhoog mist bijvoorbeeld de delete Drawing;

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