[Java -> c++] Ben ik raar of is C++ dat gewoon?

Pagina: 1
Acties:
  • 134 views sinds 30-01-2008
  • Reageer

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

Topicstarter
Na veel met java gemaakt te hebben ben ik sinds kort (eindelijk) eens met C++ begonnen. De applicatie die ik moet maken is qua grafische output en geheugen gebruik waarschijnlijk net iets te veel voor java, en daarnaast is het realtime aspect ook redelijk van belang zodat de keuze al snel op C++ gevallen is.

Als java gebruiker loop ik echter tegen een paar dingen aan die mij niet zo heel erg aanstaan. Nu zijn het niet onoverkomelijke problemen, maar ik wil het het liefst wel gelijk goed doen en mezelf niet een ranzige coding style aanmeten. Vandaar de volgende vraagjes:

1 Ik heb een class gemaakt. De definitie van deze class staat in de header file en de methoden zelf in de cpp file. Wat ik echter een beetje lelijk/tegenstrijdig/onoverzichtelijk vind is dat in die header file dus ook de private methoden en variabelen staan. Is er niet een nette manier om ervoor te zorgen dat in de header file alleen het public gedeelte van de class staat en in de cpp file het private gedeelte? Of hoort dit gewoon zo.

2 Het lukt me niet om een initiele waarde aan variabelen te geven in die class. In java kun je bv boolean blaat=false doen en zodra de class dan wordt aangemaakt wordt die boolean op false geinitialiseerd. Ik heb dit nu opgelost door in elke constructor een private _initVars() methode aan te roepen die alle variabelen hun initiele waarde geven. Is daar niet een mooiere oplossing voor?

3 In mijn class maak ik gebruik van een stuk dynamisch gealloceerd geheugen. Dit alloceren gebeurt met de private methode _allocArray(size...). Aan het begin van deze methode wil ik echter controleren of er niet al een stuk geheugen gealloceerd is om dit eerst vrij te kunnen geven. Nu dacht ik dat gewoon te kunnen doen door de pointer naar dat stuk geheugen te vergelijken met null, maar dan kreeg ik een segmentation error. Ik heb het nu opgelost door een extra boolean (_isAllocated) te gebruiken die wordt geinitialiseerd op false in die _initVars methode van de vorige vraag. Zelf vind ik deze oplossing een beetje lelijk, is daar niet een betere constructie voor?

PS: ik probeer ANSI C++ te schrijven en gebruik de gnu compiler onder Linux.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:16
Op dinsdag 02 juli 2002 11:21 schreef Janoz het volgende:

1 Ik heb een class gemaakt. De defenitie van deze class staat in de header file en de methoden zelf in de cpp file. Wat ik echter een beetje lelijk/tegenstrijdig/onoverzichtelijk vind is dat in die header file dus ook de private methoden en variabelen staan. Is er niet een nette manier om ervoor te zorgen dat in de header file alleen het public gedeelte van de class staat en in de cpp file het private gedeelte? Of hoort dit gewoon zo.
Het hoort gewoon zo en ik vind dat eigenlijk ook netjes dat de definitie en de implementatie gescheiden is. Zo heb je heel snel een overzicht van uit welke member-variablen en functions uw class bestaat.
In Java en C# heb je die scheiding niet en dat vind ik eigenlijk jammer. (In C++ kan je eigenlijk wel doen zoals in Java en C#, nl. de functies binnen je class-definitie uitwerken.
2 Het lukt me niet om een initiele waarde aan variabelen te geven in die class. In java kun je bv boolean blaat=false doen en zodra de class dan wordt aangemaakt wordt die boolean op false geinitialiseerd. Ik heb dit nu opgelost door in elke constructor een private _initVars() methode aan te roepen die alle variabelen hun initiele waarde geven. Is daar niet een mooiere oplossing voor?
Ik vind dat wel mooi dat je dat via de constructor moet doen, want ieder object dat je van die class instantieert moet die variablen toch initialiseren, dus wordt dat via de constructor aangeroepen.
(Ik vind het zelfs vreemd dat je dat in Java zo kan doen? Of kan dat enkel voor static members in Java?)
3 In mijn class maak ik gebruik van een stuk dynamisch gealloceerd geheugen. Dit alloceren gebeurt met de private methode _allocArray(size...). Aan het begin van deze methode wil ik echter controleren of er niet al een stuk geheugen gealloceerd is om dit eerst vrij te kunnen geven. Nu dacht ik dat gewoon te kunnen doen door de pointer naar dat stuk geheugen te vergelijken met null, maar dan kreeg ik een segmentation error. Ik heb het nu opgelost door een extra boolean (_isAllocated) te gebruiken die wordt geinitialiseerd op false in die _initVars methode van de vorige vraag. Zelf vind ik deze oplossing een beetje lelijk, is daar niet een betere constructie voor?
Hmm, ik zou niet weten waarom je die seg-fault krijgt. Volgens mij zou het toch moeten werken?

https://fgheysels.github.io/


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op dinsdag 02 juli 2002 11:29 schreef whoami het volgende:
Ik vind dat wel mooi dat je dat via de constructor moet doen, want ieder object dat je van die class instantieert moet die variablen toch initialiseren, dus wordt dat via de constructor aangeroepen.
(Ik vind het zelfs vreemd dat je dat in Java zo kan doen? Of kan dat enkel voor static members in Java?)
In java kan je zoiets doen:
code:
1
2
3
4
5
class blaaat 
{
   public int variabele = 10;
   ....
}

Ik gok dat ie dat bedoelt :)

  • The End
  • Registratie: Maart 2000
  • Laatst online: 20:45

The End

!Beginning

Zoals gezegd; punt 1 en 2 horen zo.

Punt 3:
Het kan zijn dat de initiele waarde van de pointer niet null is (ligt aan de compiler). Dus in de constructor op null zetten. Daarna kan je het vergelijken met null.


[edit] vergeet een stukje :)

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Op dinsdag 02 juli 2002 11:21 schreef Janoz het volgende:
1 Ik heb een class gemaakt. De definitie van deze class staat in de header file en de methoden zelf in de cpp file. Wat ik echter een beetje lelijk/tegenstrijdig/onoverzichtelijk vind is dat in die header file dus ook de private methoden en variabelen staan. Is er niet een nette manier om ervoor te zorgen dat in de header file alleen het public gedeelte van de class staat en in de cpp file het private gedeelte? Of hoort dit gewoon zo.
Dit heb ik nog nooit anders gezien :) Volgens mij hoort het dus gewoon zo. Het is nou eenmaal een declaratie en daar horen ook private declarations bij. Het is geen omschrijving van de classe qua syntax voor de gebruiker, dus eigenlijk snap ik je bezwaar niet :) Maar in jou geval zou ik dus m'n private vars onder m'n public interface gaan declaren.
2 Het lukt me niet om een initiele waarde aan variabelen te geven in die class. In java kun je bv boolean blaat=false doen en zodra de class dan wordt aangemaakt wordt die boolean op false geinitialiseerd. Ik heb dit nu opgelost door in elke constructor een private _initVars() methode aan te roepen die alle variabelen hun initiele waarde geven. Is daar niet een mooiere oplossing voor?
Een constructie kan zijn door een constructor te maken waarbij je alle variabelen kan initaliseren. Deze constructor kan je defualt values meegeven, echter hier neem je niet alles mee weg. Maar zover ik weet kon je gewoon het volgende doen hoor (iig in BCB)
code:
1
2
3
4
5
6
7
8
namespace blaat_blaat_domein_getal {

   class Eppie {

    private:
    bool _blaat = false;
   }
}

Maar mijn C++ kan een beetje roestig zijn :)
Echter met objecten gaat dit niet zo makkelijk (en ook niet als ze static primitieven zijn geloof ik). Deze moet je initialiseren met een aparte syntax
code:
1
2
3
4
5
6
7
8
9
10
11
12
namespace blaat_blaat_domein_getal {

   class Eppie {

    private:
    bool _blaat  = false;
    Andereclasse _boeh;

    public:
    Eppie( Andereclasse boeh ) : _boeh( boeh );
   }
}

Again m'n C++ is roestig :) en ik kan het even niet hier nakijken.
3 In mijn class maak ik gebruik van een stuk dynamisch gealloceerd geheugen. Dit alloceren gebeurt met de private methode _allocArray(size...). Aan het begin van deze methode wil ik echter controleren of er niet al een stuk geheugen gealloceerd is om dit eerst vrij te kunnen geven. Nu dacht ik dat gewoon te kunnen doen door de pointer naar dat stuk geheugen te vergelijken met null, maar dan kreeg ik een segmentation error. Ik heb het nu opgelost door een extra boolean (_isAllocated) te gebruiken die wordt geinitialiseerd op false in die _initVars methode van de vorige vraag. Zelf vind ik deze oplossing een beetje lelijk, is daar niet een betere constructie voor?
Initialiseer je pointer op NULL en vergelijk daar mee. Dat zou toch geen probleem moeten geven
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
namespace blaat_blaat_domein_getal {

   class Eppie {

    private:
    Nogeenandereclass * _blaat = NULL;

    public:
    alloceerEnzo( ) {
       
       if( _blaat != NULL ) {
        //bestaat al  
        delete _blaat;
       }
       _blaat = new Nogeenandereclass( 4 , 6 );
    }
   }
}

Even lelijk inline declared, maar dat boeit ff niet
[/quote]

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:16
Op dinsdag 02 juli 2002 11:32 schreef ACM het volgende:

In java kan je zoiets doen:
code:
1
2
3
4
5
class blaaat 
{
   public int variabele = 10;
   ....
}

Ik gok dat ie dat bedoelt :)
Zoiets vermoedde ik al. :)
Maar toch kan ik er niet aan doen, ik vind dat een 'ranzige' constructie...

https://fgheysels.github.io/


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Op dinsdag 02 juli 2002 11:21 schreef Janoz het volgende:
1. Ik heb een class gemaakt. De definitie van deze class staat in de header file en de methoden zelf in de cpp file. Wat ik echter een beetje lelijk/tegenstrijdig/onoverzichtelijk vind is dat in die header file dus ook de private methoden en variabelen staan. Is er niet een nette manier om ervoor te zorgen dat in de header file alleen het public gedeelte van de class staat en in de cpp file het private gedeelte? Of hoort dit gewoon zo.
Wat je wel kunt doen is een 'interface' (een volledig abstracte klasse dus) maken voor de klasse met alleen de public members en die voor 'de buitenwereld' zichbaar maken.
whoami:
(Ik vind het zelfs vreemd dat je dat in Java zo kan doen? Of kan dat enkel voor static members in Java?)
In Java is dat syntactische suiker: de initializatie-code wordt gewoon in de constructor gezet.

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:16
Op dinsdag 02 juli 2002 11:41 schreef Glimi het volgende:

Maar in jou geval zou ik dus m'n private vars onder m'n public interface gaan declaren.
Waarom?
Maar zover ik weet kon je gewoon het volgende doen hoor (iig in BCB)
code:
1
2
3
4
5
6
7
8
namespace blaat_blaat_domein_getal {

   class Eppie {

    private:
    bool _blaat = false;
   }
}

Maar mijn C++ kan een beetje roestig zijn :)
Ik kan het hier nu niet uitproberen, maar het zou mij tenzeerste verbazen als dat mogelijk is.

https://fgheysels.github.io/


Verwijderd

2 Het lukt me niet om een initiele waarde aan variabelen te geven in die class. In java kun je bv boolean blaat=false doen en zodra de class dan wordt aangemaakt wordt die boolean op false geinitialiseerd. Ik heb dit nu opgelost door in elke constructor een private _initVars() methode aan te roepen die alle variabelen hun initiele waarde geven. Is daar niet een mooiere oplossing voor?
In C++ gaat dit via de initializer list, dus bijvoorbeeld zo:
code:
1
2
3
4
5
6
class Blaat {
public:
  int var;
  ...
  Blaat() : var = 0 {}
}

Achter de constructor naam komt : dan de initialisaties en dan de definitie van de constructor, zodat je zeker weet dat zelfs in de constructor zelf, de variabelen al geinitialiseerd zijn.

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Op dinsdag 02 juli 2002 11:43 schreef whoami het volgende:
Waarom?
Erg veel mensen vinden het belangrijk dat er eerst alle public zut in een class staat en onderaan in de .h pas de private parts :P. Maar omdat ik het nogal vaag opschreef, zal ik het verduidelijken met een voorbeeld
code:
1
2
3
4
5
6
7
8
9
10
11
12
namespace blaat_blaat_domein_getal {

   class Eppie {

    public:
        //hier alle methodes die de interface
        //van de class declaren

    private:
        //Hier de variabelen en de helper methods
   }
}


Dit bedoel ik dus met de interface. De interface van de classe dus en niet een pure abstracte class. Excuus :)
Ik kan het hier nu niet uitproberen, maar het zou mij tenzeerste verbazen als dat mogelijk is.
Ik ook niet, vandaar de disclaimer erbij. Maar met primitieven lijkt het me ook niet zo'n probleem eigenlijk, of krijg ik voor deze opmerking een C++ verbod :P

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Met VC++ en GCC werkt het iig niet :)
code:
1
2
3
4
bla.cpp:18: ANSI C++ forbids initialization of member `_blaat'
bla.cpp:18: making `_blaat' static
bla.cpp:18: ANSI C++ forbids in-class initialization of 
        non-const static member `_blaat'

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

Topicstarter
Over die header:

Ik was ook al tegen gekomen dat dat gewoon zo hoorde, maar ik vond het zelf in eerste instantie logischer dat het private gedeelte gewoon binnen de class bleef. In de header files hoef je de mensen dan niet lastig te vallen met allemaal private methoden.

Denk fout is waarschijnlijk dat ik er een beetje vanuit ging dat de headerfile wordt gebruikt door mensen die gebruik willen maken van je lib ipv dat het gewoon voor de compiler bedoeld is. Ik wilde eigenlijk gewoon zeker weten of het niet fout was wat ik deed :)..
Op dinsdag 02 juli 2002 11:41 schreef Glimi iets over initele waarden toekennen
Als ik dat doe krijg ik van m'n compiler de melding dat ik er const voor moet zetten :).

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:16
Op dinsdag 02 juli 2002 12:01 schreef Janoz het volgende:

Als ik dat doe krijg ik van m'n compiler de melding dat ik er const voor moet zetten :).
Vraagje voor de goeroe's:
Wordt een const-member automatisch een static member-variable in C++?

https://fgheysels.github.io/


  • The End
  • Registratie: Maart 2000
  • Laatst online: 20:45

The End

!Beginning

Op dinsdag 02 juli 2002 12:03 schreef whoami het volgende:

[..]

Vraagje voor de goeroe's:
Wordt een const-member automatisch een static member-variable in C++?
Even opgezocht.. Volgens MSDN is const default static in C++ en niet default static in C.

Verwijderd

Op dinsdag 02 juli 2002 12:07 schreef The End het volgende:

[..]

Even opgezocht.. Volgens MSDN is const default static in C++ en niet default static in C.
Volgens mij is dat niet waar: je kan een non-static const hebben, die dus voor elke instantie van die class een andere waarde kan hebben (toegekend in de initializer list). Een static const heeft uiteraaard 1 waarde voor elke instantie van die class.

/edit: hier zie je meteen een mooi voorbeeld van het nut van een initializer list: het zou namelijk onmogelijk zijn een const een waarde te geven in de constructor, omdat een const nooit een andere waarde toegewezen kan worden, hij moet direct bij het maken zijn waarde krijgen. Door de initializer list kan hij echter toch een waarde krijgen die afhangt van b.v. een argument van de constructor.

Verwijderd

Op dinsdag 02 juli 2002 11:55 schreef marcusk het volgende:
Met VC++ en GCC werkt het iig niet :)
Natuurlijk werkt het niet! Elke compiler die zoiets toestaat is of hersendood, of onmenselijk slim. Waarom? Omdat de compiler in complexe situaties onmogelijk kan ontdekken welk member eerst te initialiseren (dit is ook een probleem met statics).
code:
1
2
3
4
5
class Blah {
private:
  int x= y + 1;
  int y= 3;
}

  • The End
  • Registratie: Maart 2000
  • Laatst online: 20:45

The End

!Beginning

Op dinsdag 02 juli 2002 12:09 schreef John_Smith het volgende:

[..]

Volgens mij is dat niet waar: je kan een non-static const hebben, die dus voor elke instantie van die class een andere waarde kan hebben (toegekend in de initializer list). Een static const heeft uiteraaard 1 waarde voor elke instantie van die class.
Ik zei ook 'default', dus het hoeft niet :)

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:16
Op dinsdag 02 juli 2002 12:09 schreef John_Smith het volgende:

[..]

Volgens mij is dat niet waar: je kan een non-static const hebben, die dus voor elke instantie van die class een andere waarde kan hebben (toegekend in de initializer list). Een static const heeft uiteraaard 1 waarde voor elke instantie van die class.
Moet een const niet bij de declaratie geinitialiseerd worden?
Als dat zo is, dan kan een const toch geen verschillende waardes hebben binnen 2 instanties van die class?

https://fgheysels.github.io/


Verwijderd

Op dinsdag 02 juli 2002 12:12 schreef whoami het volgende:

[..]

Moet een const niet bij de declaratie geinitialiseerd worden?
Als dat zo is, dan kan een const toch geen verschillende waardes hebben binnen 2 instanties van die class?
Zie mijn edit hierboven: hij kan dus verschillende waardes krijgen omdat hij in de initializer list met b.v. een argument van de constructor wordt geinitialiseerd.

/edit: voorbeeld:
code:
1
2
3
4
5
6
class Blaat {
public:
  const int s;
  
  Blaat(int size) : s(size) {}
}

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op dinsdag 02 juli 2002 12:11 schreef mietje het volgende:
Natuurlijk werkt het niet! Elke compiler die zoiets toestaat is of hersendood, of onmenselijk slim. Waarom? Omdat de compiler in complexe situaties onmogelijk kan ontdekken welk member eerst te initialiseren (dit is ook een probleem met statics).
code:
1
2
3
4
5
class Blah {
private:
  int x= y + 1;
  int y= 3;
}
Java "kan" het wel, maar accepteert ook geen functies/berekeningen etc.
Alleen waarden.

Als je het anders/complexer wilt doen moet je daarvoor uiteraard de boel in de constructor regelen.

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Ik zou zeggen doe het consequent en zet alles in de initializer list.
Trouwens wist je dat ... een static const float niet 'in-line' geinitaliseerd kan worden itt een int? :)

Janoz ik zou die functies _initVars(), _allocArray() en _isAllocated() er maar uitgooien. Voor de gemiddelde programmeur is een respectievelijke: constructor, new en if(p != 0) duidelijker dan de aanroep van die functies.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:21
Op dinsdag 02 juli 2002 12:03 schreef whoami het volgende:
Vraagje voor de goeroe's:
Wordt een const-member automatisch een static member-variable in C++?
Als wannabe-goeroe probeer ik dat natuurlijk gewoon uit. Ik had zelf verwacht van niet en inderdaad:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class A {
  A() : x(1) { };
  int x;
};

class B {
  B() : x(1) { };
  const int x;
};

class C {
  C() { x=1; };
  static int x;
};

int main() {
  cout << sizeof(A) << endl
     << sizeof(B) << endl
     << sizeof(C) << endl;
}

Levert op:
code:
1
2
3
4
4
1

Waarbij die ene byte als opvulling dient (om o.a. pointervergelijkingen mogelijk te maken) en te vervallen komt wanneer de klasse échte informatie bevat.

De const-variable wordt dus wel degelijk in het object opgeslagen. De reden hiervoor is dat de constante waarde pas in de constructor vastgelegd wordt.

Dit is bijvoorbeeld geldige code:
code:
1
2
3
4
5
class B
{
      B(int y) : x(y) { };
      const int x;
};

Het moge duidelijk zijn dat de compiler in dit geval geen static variabele kan introduceren.

Edit: 42389743 mensen waren me voor. :+

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 22:38
Op dinsdag 02 juli 2002 12:03 schreef whoami het volgende:

[..]

Vraagje voor de goeroe's:
Wordt een const-member automatisch een static member-variable in C++?
Nee; zeker niet.
't is heel anders voor non-members want static betekent iets heel anders voor globals als voor members

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


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 22:38
Op dinsdag 02 juli 2002 11:21 schreef Janoz o.a. het volgende:
1 Ik heb een class gemaakt. De definitie van deze class staat in de header file en de methoden zelf in de cpp file. Wat ik echter een beetje lelijk/tegenstrijdig/onoverzichtelijk vind is dat in die header file dus ook de private methoden en variabelen staan. Is er niet een nette manier om ervoor te zorgen dat in de header file alleen het public gedeelte van de class staat en in de cpp file het private gedeelte? Of hoort dit
gewoon zo.
De standaard methode hier heet "pimpl"; waarin de de class in de .h alleen een pointer naar een implementatie class bevat. Dat type is dan met een
code:
1
class MyClass_impl;

gedeclared; de definitie staat in de .cpp. De ctors van MyClass doen dan gewoon een new; de dtor een delete (of je gebruikt een smart pointer).
2 Het lukt me niet om een initiele waarde aan variabelen te geven in die class.
Zoals gezegd, initializer list ( : member( initial_val ), etc.
3 In mijn class maak ik gebruik van een stuk dynamisch gealloceerd geheugen. Dit alloceren gebeurt met de private methode _allocArray(size...).
Niet doen; gebruik std::vector of andere container classes.

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


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

Topicstarter
Op dinsdag 02 juli 2002 12:36 schreef MSalters het volgende:

[..]

De standaard methode hier heet "pimpl"; waarin de de class in de .h alleen een pointer naar een implementatie class bevat. Dat type is dan met een
code:
1
class MyClass_impl;

gedeclared; de definitie staat in de .cpp. De ctors van MyClass doen dan gewoon een new; de dtor een delete (of je gebruikt een smart pointer).
Ik neem niet aan dat dit gebruikelijk is? Het gaat me er niet perse om dat mensen niet kunnen achterhalen hoe mijn class werkt. Het ging me er meer om om de headerfile wat overzichtelijker te houden.
Zoals gezegd, initializer list ( : member( initial_val ), etc.
Hoef je die dan maar 1x te gebruiken? Mijn class heeft namelijk een aantal constructoren (1 zonder parameters, 1met bestandsnaam, een paar met afmetingen in een aantal verschillende types) Om bij elke weer het stukje te moeten CnP-en vraagt een keer om een fout (Waneer een extra var moet worden geinitialiseerd, of een var anders moet worden geinitialiseerd (als ik van unsigned toch overstap op signed) is het het makkelijkst als dit gewoon op 1 plek staat)
Niet doen; gebruik std::vector of andere container classes.
mwah .. de dataset gaan wel tot 2048x1024x1024xSHORT. En die 4 GB aan geheugen heb ik het liefst zoveel mogelijk zelf onder controle ;)


-- Nu nog ff wat anders... Ik heb wat problemen met mijn copy constructor:
code:
1
2
3
4
5
6
7
ShortVolume::ShortVolume(const ShortVolume& s){
  _initVars();
  if (s.hasData()){
    _allocateArray(s.getXSize(),s.getYSize(),s.getZSize());
    //Hier moet de complete dataset nog worden gekopieerd
  }
}

geeft:
ShortVolume.cpp: In method `ShortVolume::ShortVolume(const ShortVolume &)':
ShortVolume.cpp:19: passing `const ShortVolume' as `this' argument of `bool ShortVolume::hasData()' discards qualifiers
ShortVolume.cpp:20: passing `const ShortVolume' as `this' argument of `long unsigned int ShortVolume::getXSize()' discards qualifiers
ShortVolume.cpp:20: passing `const ShortVolume' as `this' argument of `long unsigned int ShortVolume::getYSize()' discards qualifiers
ShortVolume.cpp:20: passing `const ShortVolume' as `this' argument of `long unsigned int ShortVolume::getZSize()' discards qualifiers


Nou heb ik geen ID hoe ik dit op moet lossen. Ik dacht eerst dat, doordat het adres word megegeven je gebruik moet maken van (*s). of s-> ipv s., maar dat werd ook niet gepikt?

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Orphix
  • Registratie: Februari 2000
  • Niet online
Je discard de qualifier, oftewel je geeft een const object mee aan een functie die geen const verwacht (en dus eventueel gaat muteren). Dit mag dus niet. Daarom is het zaak om zo vroeg mogelijk consequent met const te beginnen omdat dit achteraf aanpassen een lawine-effect geeft en je hele applicatie in 1x invalide is.

Je moet dus getXSize(), getYSize(), getZSize() alledrie const maken. Dit geeft aan dat deze functies het object niet bewerken.
Ook de parameters in _allocateArray() moeten met const worden aangeduid.

Je maakt hier trouwens geen gebruik van een pointer maar van een reference. Een reference benader je hetzelfde als een 'gewoon' object op de stack. Je hoeft dus niet de -> operator te gebruiken.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

Topicstarter
K thanx :)

Ik had al zo'n vermoeden (hoe weet de compiler nou waneer ik het object niet verander) maar ik ga dus maar ff de methode's aanpassen.. Nu eerst koffie :)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:21
Op dinsdag 02 juli 2002 12:51 schreef Janoz het volgende:
Hoef je die dan maar 1x te gebruiken? Mijn class heeft namelijk een aantal constructoren (1 zonder parameters, 1met bestandsnaam, een paar met afmetingen in een aantal verschillende types) Om bij elke weer het stukje te moeten CnP-en vraagt een keer om een fout (Waneer een extra var moet worden geinitialiseerd, of een var anders moet worden geinitialiseerd (als ik van unsigned toch overstap op signed) is het het makkelijkst als dit gewoon op 1 plek staat)
In het algemeen is het zinnig om zo min mogelijk constructors te maken, door gebruik te maken van default arguments. Als dat niet afdoende helpt, heb je helaas geen andere optie dan toch een initialisatiemethode te schrijven en die aan te roepen in de constructor.

Het 'echte' werk moet uiteindelijk toch in de constructor gebeuren. De overige gepresenteerde mogelijkheden zijn in feite vooral handigheidjes om in veelvoorkomende situaties code te kunnen besparen.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 22:38
Op dinsdag 02 juli 2002 12:51 schreef Janoz het volgende:

[pimpl idioom]

Ik neem niet aan dat dit gebruikelijk is? Het gaat me er niet perse om dat mensen niet kunnen achterhalen hoe mijn class werkt. Het ging me er meer om om de headerfile wat overzichtelijker te houden.
Gebruikelijk voor grotere, abstractere classes.
[ Initializer lists ]

Hoef je die dan maar 1x te gebruiken? Mijn class heeft namelijk een aantal constructoren (1 zonder parameters, 1met bestandsnaam, een paar met afmetingen in een aantal verschillende types) Om bij elke weer het stukje te moeten CnP-en vraagt een keer om een fout (Waneer een extra var moet worden geinitialiseerd, of een var anders moet worden geinitialiseerd (als ik van unsigned toch overstap op signed) is het het makkelijkst als dit gewoon op 1 plek staat)
Nee, in principe moeten ze herhaald worden. Alleen als een groep van members structureel hetzelfde worden geinitialiseerd dan is er vrijwel zeker sprake van een gemiste abstractie. Gooi die members in een eigen class, met een enkele default ctor. De originele class zal die default ctor gewoon aanroepen om deze members te initialiseren.
mwah .. de dataset gaan wel tot 2048x1024x1024xSHORT. En die 4 GB aan geheugen heb ik het liefst zoveel mogelijk zelf onder controle ;)
Tsja, dan heb je dus een 64 bits machine nodig. Maar afgezien daarvan zie ik geen reden om van standaard spul af te wijken. Ik zou waarschijnlijk wel std::deque gebruiken ipv std::vector voor de eerste [twee] dimensie[s].
-- Nu nog ff wat anders... Ik heb wat problemen met mijn copy constructor:
const qualification op aangeroepen members mist idd.

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


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

Topicstarter
Op dinsdag 02 juli 2002 13:25 schreef MSalters het volgende:

Nee, in principe moeten ze herhaald worden. Alleen als een groep van members structureel hetzelfde worden geinitialiseerd dan is er vrijwel zeker sprake van een gemiste abstractie. Gooi die members in een eigen class, met een enkele default ctor. De originele class zal die default ctor gewoon aanroepen om deze members te initialiseren.
Een gemiste abstractie laag? Als ik mijn minimum standaard op MAXSHORT, mijn maximum op MINSHORT, een pointer naar de data op NULL en de x,y en z size op 0 wil hebben, moet er dan een class tussen? Dat leek mij juist overkill.
Tsja, dan heb je dus een 64 bits machine nodig. Maar afgezien daarvan zie ik geen reden om van standaard spul af te wijken. Ik zou waarschijnlijk wel std::deque gebruiken ipv std::vector voor de eerste [twee] dimensie[s].
4GB is nog net met 32 bit te adresseren :).. Het is odm ook meer een theoretisch maximum. Ik heb echter wel een 64-bit platform tot mijn beschikking om met de echt grote datasets te kunnen werken.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:21
Op dinsdag 02 juli 2002 13:33 schreef Janoz het volgende:
Een gemiste abstractie laag? Als ik mijn minimum standaard op MAXSHORT, mijn maximum op MINSHORT, een pointer naar de data op NULL en de x,y en z size op 0 wil hebben, moet er dan een class tussen? Dat leek mij juist overkill.
Ik ben van mening dat een klasse een bepaald gedrag over zekere eigenschappen hoort te definiëren. Een extra klasse, die geen gedrag toevoegd, geen datavelden toevoegt en uitsluitend door een enkele klasse gespecialiseerd wordt, heeft volgens die redenatie geen bestaansrecht, omdat 'ie alleen in waarde verschilt van de gespecificeerde klasse, wat eigenlijk geen verschil is in klasse is.

De meest geschikte (algemene) oplossing lijkt mij nog steeds een private methode die in de constructor aangeroepen wordt, om de default waarden in te stellen. Eventueel kun je 'm inlinen in je klassedefinitie om de defaultwaarden in de definitie zichtbaar te maken.

In dit geval zou ik gewoon alle waarden direct in de initializer list zetten; ze zijn redelijk triviaal.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 22:38
Op dinsdag 02 juli 2002 13:33 schreef Janoz het volgende:

[..]

Een gemiste abstractie laag? Als ik mijn minimum standaard op MAXSHORT, mijn maximum op MINSHORT, een pointer naar de data op NULL en de x,y en z size op 0 wil hebben, moet er dan een class tussen? Dat leek mij juist overkill.
Als je die waarden gebruikt, heb je dan eigenlijk al een object? Of heb je een soort "proto-object" wat later nog ingevuld moet worden? Kortom, kun je de definitie van dit soort objecten niet uitstellen tot je echte waarden hebt voor data,x,y en z?
PS. als x,y en z de grootte van data beschrijven, dan horen die natuurlijk samen met data in 1 object, los van min_value en max_value

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