[C++]Conversion? (n00b vraagje, heb al UTFS)

Pagina: 1
Acties:

  • Toiletman
  • Registratie: Februari 2000
  • Laatst online: 13-09 14:36
nou, kom ik weer met vast een n00b vraag, maar ik snap weer niet wat ik fout doe:
code:
1
itsTribeName = "Kel Ress";

Dit stukkie Code komt uit een Constructor voor m'n Player class, en dit stukkie code zit dan weer binnen een switch statement, maar daar zit het probleem niet (geloof ik?).
itsTribeName is een String, en String is een klasse die ik uit een boek heb gekopieerd (jaja, ik moet std classes gebruiken, ik weet het ;)). Die String class maakt dus een char array die precies groot genoeg is voor de string waarmee ie gevoerd wordt.
Nou is de error die ik krijg van de compiler:
code:
1
2
3
Error E2285 e:\cpp spul\targui\source\Player.cpp 
13: Could not find a match for 'String::operator =(char *)'
in function Player::Player(String &,COLOR)

de operator= van String ziet d'r zo uit:
code:
1
String& operator= (const String&);

en String heeft ook een constructor die een char* neemt, dus nu snap ik niet waarom dat kreng "Kel Ress" niet gewoon ombouwt tot String en daarmee klaar is :(
het zal wel weer met const en references te maken hebben... want daar schijn ik niet zo goed in te zijn :).
dus als iemand dit probleem ff voor me kan ophelderen dan zal ik je eeuwig dankbaar zijn :o

Het zal wel met die String& aan de left hand side van = te maken hebben... maareh, om die operator= te overloaden is alleen het returntype veranderen niet genoeg als ik het goed heb?
Dus het zal d'r wel op neerkomen dat ik stiekem toch een operator= met een char* moet gaan schrijven, maar jah, als jullie me nog wat werk (jajaja ik ben lui) kunnen besparen met een andere oplossing... graag :9

Only dead fish go with the flow


  • Toiletman
  • Registratie: Februari 2000
  • Laatst online: 13-09 14:36
trouwens gelijk nog een (retorisch?) vraagje...
het is niet mogelijk een array van je eigen objecten te initializen of wel?
(ik heb een object met een constructor die 2 arguments heeft, en die wil ik graag in een array hebben... met initialization, omdat die twee arguments de rest van het programma niet hoeven te veranderen.)

Only dead fish go with the flow


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

curry684

left part of the evil twins

Op maandag 21 januari 2002 20:22 schreef Toiletman het volgende:
Dus het zal d'r wel op neerkomen dat ik stiekem toch een operator= met een char* moet gaan schrijven, maar jah, als jullie me nog wat werk (jajaja ik ben lui) kunnen besparen met een andere oplossing... graag :9
Mail de hele code maar door, heb je binnen een half uur antwoord. Zie m'n profile voor addy.

(zie uit het verhaal hierboven zo snel geen grove fouten, die definities mogen an sich maar de implementatie kan verneukt zijn).

Professionele website nodig?


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

curry684

left part of the evil twins

Op maandag 21 januari 2002 20:41 schreef Toiletman het volgende:
trouwens gelijk nog een (retorisch?) vraagje...
het is niet mogelijk een array van je eigen objecten te initializen of wel?
(ik heb een object met een constructor die 2 arguments heeft, en die wil ik graag in een array hebben... met initialization, omdat die twee arguments de rest van het programma niet hoeven te veranderen.)
Array van pointers.
code:
1
2
3
4
Object* MyObjects[20];

for(int i = 0; i != 20; i++)
  MyObjects[i] = new Object(ArgA, ArgB);

Professionele website nodig?


  • Toiletman
  • Registratie: Februari 2000
  • Laatst online: 13-09 14:36
gemaild... thx

ik heb al een list gemaakt voor dit programma...en die heeft ook een operator[]... alleen heeft die nog wat extra functionaliteit die hier overbodig zou zijn. Maar ik vroeg me toch af of ik daarbij ook een multidimensionale list van kan maken door [][] te gebruiken, of moet ik daar operator[] nog op een speciale manier voor overloaden?

Anyways, ik weet nog niet of ik een dubbele array met pointers ga maken of toch wat Setfuncties ga maken voor die objecten... allebei vind ik het nogal irri oplossingen...
setfuncties die je maar 1 keer gebruikt zijn nogal zinloos (toch?)
array van pointers geeft weer zo'n lading extra ->'s maar ja, dat moet allemaal wel weg te werken zijn... objecten gewoon initializen zou makkelijker zijn :(

Only dead fish go with the flow


  • Toiletman
  • Registratie: Februari 2000
  • Laatst online: 13-09 14:36
en ja hoor.... het probleem zat weer eens bij const.... ik begin steeds meer een hekel te krijgen aan dat statement... ghehe...
als d'r mensen zijn die zich geroepen voelen de pro's en cons van const te bespreken... ga je gang.....
ik begrijp d'r iig weinig van, ik wil d'r dingen mee die het niet kan en dergelijke...

zoals met dit probleem had ik een member variable const gemaakt omdat ik wilde dattie na de constructie van het object niet meer zou veranderen (maar wel bij iedere instantie van een object anders zou kunnen zijn). Hier blijkt const dus niet voor te zijn... lijkt mij toch vrij onlogisch omdat een constructor een object maar 1 keer verandert... maar ja, const zal wel andere dingen moeten doen, dus als jullie me daar eens even over willen inlichten?

Only dead fish go with the flow


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

curry684

left part of the evil twins

Hoofdstuk 1:
The const keyword specifies that a variable's value is constant and tells the compiler to prevent the programmer from modifying it.
code:
1
2
3
4
5
6
7
8
// constant_values1.cpp
// C2166 expected
void main()
{
   const int i = 5;
   i = 10; // C2166
   i++;    // C2105
}

In C++, you can use the const keyword instead of the #define preprocessor directive to define constant values. Values defined with const are subject to type checking, and can be used in place of constant expressions. In C++, you can specify the size of an array with a const variable as follows:
code:
1
2
3
4
5
6
7
// constant_values2.cpp
const int maxarray = 255;
char store_char[maxarray];  // Legal in C++; illegal in C

int main()
{
}

In C, constant values default to external linkage, so they can appear only in source files. In C++, constant values default to internal linkage, which allows them to appear in header files.

The const keyword can also be used in pointer declarations.
code:
1
2
3
4
5
6
7
8
9
// constant_values3.cpp
// C2166 expected
void main()
{
   char *mybuf, *yourbuf;
   char *const aptr = mybuf;  // Constant pointer
   *aptr = 'a';   // OK
   aptr = yourbuf;
}

A pointer to a variable declared as const can be assigned only to a pointer that is also declared as const.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
// constant_values4.cpp
#include <stdio.h>
void main()
{
   const char *mybuf = "test";
   char *yourbuf = "test2";
   printf("%s\n", mybuf);

   const char *bptr = mybuf;   // Pointer to constant data
   printf("%s\n", bptr);
   
   // *bptr = 'a';   // Error
}

You can use pointers to constant data as function parameters to prevent the function from modifying a parameter passed through a pointer.

For objects that are declared as const, you can only call constant member functions. This ensures that the constant object is never modified.
code:
1
2
birthday.getMonth();    // Okay
birthday.setMonth( 4 ); // Error

You can call either constant or nonconstant member functions for a nonconstant object. You can also overload a member function using the const keyword; this allows a different version of the function to be called for constant and nonconstant objects.

You cannot declare constructors or destructors with the const keyword.

C and C++ const Differences

When you declare a variable as const in a C source code file, you do so as:

const int i = 2;
You can then use this variable in another module as follows:

extern const int i;
But to get the same behavior in C++, you must declare your const variable as:

extern const int i = 2;
If you wish to declare an extern variable in a C++ source code file for use in a C source code file, use:

extern "C" const int x=10;
to prevent name mangling by the C++ compiler.

Professionele website nodig?


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

curry684

left part of the evil twins

Hoofdstuk 2:
Declaring a member function with the const keyword specifies that the function is a "read-only" function that does not modify the object for which it is called.

To declare a constant member function, place the const keyword after the closing parenthesis of the argument list. The const keyword is required in both the declaration and the definition. A constant member function cannot modify any data members or call any member functions that aren't constant.

Example:
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
// constant_member_function.cpp
class Date
{
public:
   Date( int mn, int dy, int yr );
   int getMonth() const;     // A read-only function
   void setMonth( int mn );   // A write function; can't be const
private:
   int month;
};

int Date::getMonth() const
{
   return month;      // Doesn't modify anything
}
void Date::setMonth( int mn )
{
   month = mn;      // Modifies data member
}
void main()
{
   Date MyDate( 7, 4, 1998 );
   const Date BirthDate( 1, 18, 1953 );
   MyDate.setMonth( 4 );    // Okay
   BirthDate.getMonth();    // Okay
   BirthDate.setMonth( 4 ); // C2662 Error
}

Professionele website nodig?


Verwijderd

Dat snap ik zelfs nog!! :+

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op maandag 21 januari 2002 22:35 schreef Toiletman het volgende:
en ja hoor.... het probleem zat weer eens bij const.... ik begin steeds meer een hekel te krijgen aan dat statement... ghehe...
als d'r mensen zijn die zich geroepen voelen de pro's en cons van const te bespreken... ga je gang.....
ik begrijp d'r iig weinig van, ik wil d'r dingen mee die het niet kan en dergelijke...

zoals met dit probleem had ik een member variable const gemaakt omdat ik wilde dattie na de constructie van het object niet meer zou veranderen (maar wel bij iedere instantie van een object anders zou kunnen zijn). Hier blijkt const dus niet voor te zijn... lijkt mij toch vrij onlogisch omdat een constructor een object maar 1 keer verandert... maar ja, const zal wel andere dingen moeten doen, dus als jullie me daar eens even over willen inlichten?
Wat jij wilt kan via een private variabele. Op deze manier kan alleen je eigen class deze veranderen; wat je dus alleen wil doen in de constructor.

En om kort te zeggen waarom const er is:
Het is een middel om je programma stabieler/duidelijker en efficienter te maken.
Stabieler - als de gebruiker van je class iets niet mag veranderen dan kan je nooit voor (moeilijk te traceren) bugs komen te staan omdat per ongeluk bijvoorbeeld een interne counter een andere waarde krijgt van buitenaf.
Duidelijker - voor de gebruiker is het duidelijk dat een const functie alleen een waarde uitrekent of opvraagt. Je kan goed raden waardoor een object wel of niet wordt gebruikt. (zie bv strcpy(), aan de const kan je zien welke als bron en welke als doel wordt gebruikt)
Sneller - omdat de compiler weet dat het object niet verandert kan het verschillende truukjes toepassen om het geheel wat sneller te maken.

Het is een goede gewoonte om const te gebruiken waar het hoort. Op die manier verzeker je jezelf -en anderen- ervan dat je niet halverwege het project gaat 'sjoemelen' maar mooie setters-getters blijft schrijven en duidelijke member methods. Ik moet eerlijk toegeven dat ik me dit ook niet echt eigen heb gemaakt maar ik probeer het de laatste tijd zoveel mogelijk. Wat je niet moet proberen is om 'achteraf' nog variabelen of methods const gaat maken. Probeer het maar eens, je zal zien hoeveel errors je dan gaat krijgen :)

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

curry684

left part of the evil twins

En om een belangrijke passage aan te halen uit de docs die ik hierboven postte:
You can also overload a member function using the const keyword; this allows a different version of the function to be called for constant and nonconstant objects.
Dit is een HEEL belangrijke feature zodra je een string-class of zo met copy-on-demand gaat schrijven. Je schrijft van bepaalde functies zowel een const als een non-const implementatie, waarvan je weet dat de const variant nooit een copy hoeft te verrichten.

Dit gaat niet meer over procentjes snelheidswinst die de compiler uit const kan optimaliseren, maar om een factor 2 of 3 (!!!!!) op complete programmas die op const gestoeld zijn.

Professionele website nodig?


  • Bananeman
  • Registratie: Juli 2000
  • Niet online
Op maandag 21 januari 2002 22:35 schreef Toiletman het volgende:
zoals met dit probleem had ik een member variable const gemaakt omdat ik wilde dattie na de constructie van het object niet meer zou veranderen (maar wel bij iedere instantie van een object anders zou kunnen zijn).
Wat jij hier beschrijft is dat je een member variabele één keer zet en daarna nooit meer... dat kan, al weet ik niet of het is wat je wilt. Je kunt const member variabelen initialiseren op het moment dat je object wordt geconstruct:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class cTest
{
public:
   cTest( int p_Value );

private:
   const int m_ConstInt;
};

// Let op de dubbbele punt in de volgende regel ...
cTest::cTest( int p_Value ) : m_ConstInt( p_Value )
{
// Normale constructor code
}

Vóórdat de body van de constructor wordt aangeroepen krijgt m_ConstInt de waarde van p_Value. De notatie met de dubbbele punt stelt je in staat om de constructors van de basisklassen aan te roepen met bepaalde parameters, iets dat normaal gesproken niet kan omdat gewoon de constructor zonder parameters wordt genomen. Maar je kunt op deze manier dus ook const member variabelen initialiseren.

Nadeel is wel dat de waarde, die de const member variabele moet krijgen, bekend moet zijn op het moment dat je instantie wordt aangemaakt. In de body van je constructor ben je al te laat, zelfs dan kan een const member variabele niet meer worden gewijzigd.

Wat je volgens mij eigenlijk wilt is de innerlijke werking van je klasse en alle daarbij behorende data afschermen, encapsulatie dus. Dan krijg je te maken met accessors (getters en setters). Staat in elke docje over OO.

Motor-forum.nl


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

curry684

left part of the evil twins

Op maandag 21 januari 2002 23:06 schreef Bananeman2002 een correct stukje
Oeps even vergeten ja dat je op die manier const members wel mag zetten. Niet echt een gangbare constructie overigens.

Je kunt ook een private membervalue echt const voor alle classes van het betreffende type maken door 'm static const te declareren. Scheelt een hoop opslagruimte/overhead doordat je maar 1 copy van de waarde per classtype hebt, maar in dit geval wil de Toiletman inderdaad precies wat jij omschrijft.

* curry684 slaps himself very hard. |:(

(hoe is het trouwens bij CMG?)

Professionele website nodig?


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
M.a.w.:

Je hebt een constructor nodig die een "const char *" accepteerd. Of was het nou "char const *".
Ben altijd in de war met die twee. :'(

"const char *" is toch een char pointer die constant is en "char const *" is toch een char pointer die naar een constante char wijst? |:( Of.... ?

HELLUP!!! :(

  • Bananeman
  • Registratie: Juli 2000
  • Niet online
Op maandag 21 januari 2002 23:26 schreef curry684 het volgende:

[..]

Oeps even vergeten ja dat je op die manier const members wel mag zetten. Niet echt een gangbare constructie overigens.
Toch wel!
Je kunt ook een private membervalue echt const voor alle classes van het betreffende type maken door 'm static const te declareren. Scheelt een hoop opslagruimte/overhead doordat je maar 1 copy van de waarde per classtype hebt, maar in dit geval wil de Toiletman inderdaad precies wat jij omschrijft.
Inderdaad, want het zaakje static maken is gewoon iets heel anders...
* curry684 slaps himself very hard. |:(

(hoe is het trouwens bij CMG?)
Prima, moet ik zeggen. En hoe is 't bij Bigback? En dan een eerlijk antwoord graag..?

Motor-forum.nl


  • Toiletman
  • Registratie: Februari 2000
  • Laatst online: 13-09 14:36
ah... da's al weer een lading info... waar komt dat uit?

[blaat alert ON]
Ik blijf het toch vreemd vinden dat je const dus nooit voor iets zou kunnen gebruiken dat je niet kan initializen, zoals in dit voorbeeld... nu weet ik dus dat ik const daar gewoon niet kan gebruiken, maar stel nou dat ik dat wel zou willen:

Voorbeeld is m'n Player class
die bevat dus twee strings een kleur en een int. De int is constant variabel (;)) en de twee strings en kleur zijn constant per object (bij constructie worden ze aangemaakt, en veranderen daarna nooit meer).
Ik heb nu een constructor die 1 string neemt en 1 kleur, en omdat de kleur en de 2e string samenhangen, wou ik die in de constructor vast laten stellen.
de 1e string bevat de naam van de speler, de 2de string de naam van de 'stam' en de kleur hoort dan bij de stam.
Nou kan je via initialization const variabelen instellen... nu wilde ik dus in m'n constructor via een switch statement de kleur de 'stam' string laten bepalen. Maar dat mocht dus niet omdat ik m'n 'stam'string const had gemaakt.
opties:
-'stam'string niet const laten zijn
-constructor twee string-argumenten laten nemen (via een andere functie zodat ze wel onderling gelinkt zijn?)

welke van de twee is nou de beste? Eerste is lekker simpel, maar tweede zorgt toch echt voor bescherming van de tweede string (niet dat het echt nodig is, maar het gaat om het principe).

trouwens nog een vraagje:
Als ik die 'stam'string nou niet const laat zijn, maar een instantie van de klasse wel, mag ik dan in de constructor wel die String assignen, of gaat het daar dan ook al mis? (los van het feit dat een const object van die klasse niet bruikbaar is omdat ik m'n int variabel wil hebben)

dat was weer een lading gereutel, maar ja, dat const is ook een raar ding :)
[blaat alert OFF]

Only dead fish go with the flow


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

curry684

left part of the evil twins

Op maandag 21 januari 2002 23:32 schreef Bananeman2002 het volgende:
Prima, moet ik zeggen. En hoe is 't bij Bigback? En dan een eerlijk antwoord graag..?
Hehe de naam Bananeman was al een open doel, maar dan ook nog code schrijven met p_ en m_ prefixes was wel een erg open doel... pikken ze non-Hungarian bij CMG en zijn klanten wel?

En verder persoonlijk geemmer over onze respectievelijke werkgevers doen we wel via MSN ;)

Professionele website nodig?


  • Toiletman
  • Registratie: Februari 2000
  • Laatst online: 13-09 14:36
tsssk, ik kan hier niet eens meer rustig een stukje typen zonder dat d'r al een lading replies tussenstaan:
Op maandag 21 januari 2002 23:06 schreef Bananeman2002 een goed stukjke
idd een goed stukje, maar dat gebruikte ik dus al voor een heleboel dingen... idd handig, en curry heeft me ook al uitgelegd dat ik in de body van de constructor te laat ben met const dingen...
maar zie m'n vorige stukje... als ik een instantie van het object const verklaar ben ik dan ook te laat? (lol, waarom schrijf ik niet gewoon ff een testproggie daarvoor... doe 'k morgen wel als d'r niemand is die het nu weet).
Op maandag 21 januari 2002 22:54 schreef Orphix ook een al een goed stukje
Jouw post was eigenlijk nog eerder, maar ik zag em niet eerder :).
Private variables gebruik ik natuurlijk al, maar dat kan jij niet zien want je hebt m'n source niet... en dat je als je naderhand nog gaat lopen prutsen met je setters en getters const verklaren er een zooitje van maakt had ik ook al gemerkt |:(.
Ik had d'r al over gedacht om m'n functies te gaan overloaden voor const en niet const returntypes, maareh voor overloading moet je toch het soort of het aantal arguments van een functie veranderen? Ik dacht dat het niet werkte voor alleen het returntype, of heb ik dat mis?
Ennuh, misschien een andere misconceptie van mij is dat als je een functie gebruikt die niet const is, je dan efficienter bezig bent dan met een overloaded functie voor const en niet-const?

The-DDD:
het stukje zat niet in de const char* (of wat het nou was), maar aan de linkerkant... misschien ook wel aan allebei de kanten... maar dat check ik morgen wel, want als ik nu weer ga zitten proggen dan wordt het weer veelste laat voordat ik stop :).

Only dead fish go with the flow


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op maandag 21 januari 2002 23:31 schreef The - DDD het volgende:
M.a.w.:

Je hebt een constructor nodig die een "const char *" accepteerd. Of was het nou "char const *".
Ben altijd in de war met die twee. :'(

"const char *" is toch een char pointer die constant is en "char const *" is toch een char pointer die naar een constante char wijst? |:( Of.... ?

HELLUP!!! :(
andersom, bovendien is de notatie "char * const" en niet "char const *" :)

const char *str1 - hier mag je str naar een andere char laten wijzen, maar je mag de char waarnaar ie wijst niet veranderen

char * const str - hier mag je str niet naar een andere char laten wijzen, maar je mag die char wel aanpassen

en dan heb je natuurlijk nog const char * const str, waarbij je helemaal niets mag :)

PS. let op: ik heb een nieuw icoon :P

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.


  • Toiletman
  • Registratie: Februari 2000
  • Laatst online: 13-09 14:36
ik zal de foute code hier wel gelijk ff neerplempen, dan is het misschien wat duidelijker:
*****Player Declaratie*****
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Player
{
    public:
    // constructors
    Player(String& name, COLOR tribe);
//  ~Player(); use default
    // accessors
    const String& GetPlayerName() const { return itsPlayerName; }
    const String& GetTribeName() const { return itsTribeName; }
    COLOR GetCOLOR() const { return itsCOLOR; }
    int GetMoney() const { return itsMoney; }
    Area* GetVillage() const { return itsVillage; }
    // member functions
    void SetMoney(int geld) { itsMoney = geld; }
    void SetVillage(Area* dorp) { itsVillage = dorp; }
    private:
    const String itsPlayerName;
    const String itsTribeName;
    COLOR itsCOLOR;
    int itsMoney;
    Area* itsVillage;
};

*****Player Constructor*****
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
Player::Player(String& name, COLOR tribe):
    itsPlayerName(name),
    itsCOLOR(tribe),
    itsMoney(10),
    itsVillage(NULL)
{
    switch(tribe)
    {
        case BLUE:
        {
            itsTribeName = "Kel Ress";
            break;
        }
        case GREEN:
        {
            itsTribeName = "Kel Ahaggar";
            break;
        }
        case RED:
        {
            itsTribeName = "Kel Ilbakan";
            break;
        }
        case YELLOW:
        {
            itsTribeName = "Kel Ajjer";
            break;
        }   
        default:
        cout << "Illegal COLOR passed to Player constructor\n";
    }
}

Only dead fish go with the flow


  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op maandag 21 januari 2002 23:31 schreef The - DDD het volgende:
M.a.w.:

Je hebt een constructor nodig die een "const char *" accepteerd. Of was het nou "char const *".
Ben altijd in de war met die twee. :'(

"const char *" is toch een char pointer die constant is en "char const *" is toch een char pointer die naar een constante char wijst? |:( Of.... ?

HELLUP!!! :(
Na de uitleg van OiSyN toch nog ff een toevoeging.
Een 'truukje' is dat je van rechts naar links leest, dus

const char * i = variabele 'i' is een pointer naar een char die constant is
char * const i = variabele 'i' is een constante pointer naar een char

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Ok :D

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 23:11
Op maandag 21 januari 2002 20:46 schreef curry684 het volgende:

[..]
Array van pointers.
code:
1
2
3
4
Object* MyObjects[20];

for(int i = 0; i != 20; i++)
  MyObjects[i] = new Object(ArgA, ArgB);
Slecht idee, maar de reden is wat lastig uit te leggen.
Het probleem is dat je een serieus memory leak probleem hebt als er iets fout gaat (zoals out of memory).
Je kunt nl niet uitvinden waar het fout is gegaan.

Oplossingen, in volgorde van toenemende kwaliteit:
* pointers eerst op null zetten, en in catch(...)
blok allemaal deleten
* pointers eerst op null zetten, no-throw new gebruiken,
en als de laatse null is, allemaal deleten
* std::vector<Object> gebruiken ipv pointers

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: 13-09 23:11
Op maandag 21 januari 2002 23:31 schreef The - DDD het volgende:
M.a.w.:

Je hebt een constructor nodig die een "const char *" accepteerd. Of was het nou "char const *".
Ben altijd in de war met die twee. :'(

"const char *" is toch een char pointer die constant is en "char const *" is toch een char pointer die naar een constante char wijst? |:( Of.... ?

HELLUP!!! :(
Nee, zijn allebei hetzelfde: pointer to [array of] constant char.
char*const pc; is constant pointer to char. De truc is dat je van pc naar links moet lezen.

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: 13-09 23:11
Op maandag 21 januari 2002 20:22 schreef Toiletman het volgende:
nou, kom ik weer met vast een n00b vraag, maar ik snap weer niet wat ik fout doe:
code:
1
itsTribeName = "Kel Ress";

Nou is de error die ik krijg van de compiler:
code:
1
2
3
Error E2285 e:\cpp spul\targui\source\Player.cpp 
13: Could not find a match for 'String::operator =(char *)'
in function Player::Player(String &,COLOR)

de operator= van String ziet d'r zo uit:
code:
1
String& operator= (const String&);

en String heeft ook een constructor die een char* neemt, dus nu snap ik niet waarom dat kreng "Kel Ress" niet gewoon ombouwt tot String en daarmee klaar is :(
De reden heeft niks met const of references te maken, als ik het zo zie. Om te voorkomen dat de compiler zich helemaal suf moet zoeken, en uiteindelijk een conversie
const char*->Player->Game->Score->int->Number->String
verzint, is er een regel dat er maximaal een conversie
mag gebeuren. En zo te zien heb je er twee nodig. Had je
String::operator(char*) gehad, dan waren die niet nodig.

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 22 januari 2002 10:30 schreef MSalters het volgende:
Slecht idee, maar de reden is wat lastig uit te leggen.
Het probleem is dat je een serieus memory leak probleem hebt als er iets fout gaat (zoals out of memory).
Je kunt nl niet uitvinden waar het fout is gegaan.
Het was slechts ter illustratie, en daarom zonder fatsoenlijke exception handling. Overigens vergat je de kwalitatief beste optie, die ik zelf altijd gebruik:
• Reference classes gebruiken en de new operator overloaden zodat deze een bekende exception gooit bij problemen. Exit memory leaks en onduidelijke fouten.

Niet dat je gewoonlijk met out-of-memory nog veel wil salvagen (duh), je geeft de computer dan meer overlevingskans door je proces zo snel mogelijk af te laten sterven. In mijn eigen projecten is out-of-mem dan ook een 'kernel exception' die over het algemeen pas op applicatieniveau wordt afgevangen in tegenstelling tot 'reguliere exceptions'. Kernel exceptions heb ik dan ook zo opgebouwd dat ze totaal memory-extensief zijn (0 bytes overhead om te kunnen throwen geloof ik).

Professionele website nodig?


  • Toiletman
  • Registratie: Februari 2000
  • Laatst online: 13-09 14:36
Op dinsdag 22 januari 2002 11:03 schreef MSalters het volgende:

[..]

De reden heeft niks met const of references te maken, als ik het zo zie. Om te voorkomen dat de compiler zich helemaal suf moet zoeken, en uiteindelijk een conversie
const char*->Player->Game->Score->int->Number->String
verzint, is er een regel dat er maximaal een conversie
mag gebeuren. En zo te zien heb je er twee nodig. Had je
String::operator(char*) gehad, dan waren die niet nodig.
String heeft al een constructor String::String(char*) dus de conversie hoeft niet via al die dingen te gaan die jij nou noemt... ik heb nu const weggehaald... en nu werkt het dus.
Ik heb nu geloof ik alle andere consts in m'n code ook zo gezet zoals ze moeten zijn. Nu nog m'n headers en al die shit cleanen... en eens lezen hoe een makefile werkt 8-)

Only dead fish go with the flow


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 23:11
Op dinsdag 22 januari 2002 12:37 schreef Toiletman het volgende:

[..]

String heeft al een constructor String::String(char*) dus de conversie hoeft niet via al die dingen te gaan die jij nou noemt... ik heb nu const weggehaald... en nu werkt het dus.
Dat was mijn punt dus; een char* constructor mag proberen om de chars te veranderen. Dus als je const chars hebt, bv "Hello, world", dan kun je daar geen char* naar toe hebben, dus kun je er geen String van maken. Gevolg:
code:
1
String("Hello, world");

werkt niet eens.

Wat je dus wel moet doen is const toevoegen aan de char* in de ctor. Je ctor leest namelijk alleen maar de chars, en maakt er een kopie van. Als je dan ergens anders een char* hebt, is dat geen probleem. char* is bruikbaar waar een const char* gevraagd wordt.

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


  • Toiletman
  • Registratie: Februari 2000
  • Laatst online: 13-09 14:36
sorry... die constructor neemt dus een const char*... dacht dat dat wel duidelijk zou zijn omdat je anders niet String("hello world") kan doen... maar ja... ik zal voortaan wel alle const's uittypen :) ik begin echt een hekel aan die dingen te krijgen >:)

Only dead fish go with the flow


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 23:11
Op dinsdag 22 januari 2002 11:04 schreef curry684 het volgende:

Overigens vergat je de kwalitatief beste optie, die ik zelf altijd gebruik:
• Reference classes gebruiken en de new operator overloaden zodat deze een bekende exception gooit bij problemen. Exit memory leaks en onduidelijke fouten.
Waarom denk je dat Reference classes beter zijn dan direct containment zoals vector<> doet ?

BTW, standaard new geeft al een bekende exception: std::bad_alloc, hoef je niet voor te overloaden. Het probleem is de onbekende exception van de ctor, en die kun je niet in operator new aanpakken. Maar vector<> kan daar dus wel tegen.

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 22 januari 2002 15:21 schreef MSalters het volgende:
Waarom denk je dat Reference classes beter zijn dan direct containment zoals vector<> doet ?
Waarom denk je dat ik zeg dat ik ze daarom altijd gebruik? :?

Wat probeer je nu exact te zeggen?
BTW, standaard new geeft al een bekende exception: std::bad_alloc, hoef je niet voor te overloaden. Het probleem is de onbekende exception van de ctor, en die kun je niet in operator new aanpakken. Maar vector<> kan daar dus wel tegen.
Overloaden staat je allereerst toe uniformiteit in je exceptions aan te brengen, zodat je geen C++ standard library exceptions hoeft te vangen. Ten tweede mag je je eigen memory manager kiezen. Ten derde, erg handig, kun je in een eigen new-overload ervoor kiezen de HeapMinimize functionaliteit eerst te proberen voordat je definitief een out-of-memory gooit.

Professionele website nodig?


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Op dinsdag 22 januari 2002 10:57 schreef MSalters het volgende:

[..]

Nee, zijn allebei hetzelfde: pointer to [array of] constant char.
char*const pc; is constant pointer to char. De truc is dat je van pc naar links moet lezen.
Wederom:
OK :D

:P

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 23:11
Op dinsdag 22 januari 2002 16:07 schreef curry684 het volgende:
[..]
Waarom denk je dat ik zeg dat ik ze daarom altijd gebruik? :?
:? Ik heb geen idee. Omdat je denkt dat ze beter zijn, maar waarom denk je dat dit soort handle classes beter is dan direct containment? Wat zijn de technische voordelen?
Overloaden staat je allereerst toe uniformiteit in je exceptions aan te brengen, zodat je geen C++ standard library exceptions hoeft te vangen. Ten tweede mag je je eigen memory manager kiezen. Ten derde, erg handig, kun je in een eigen new-overload ervoor kiezen de HeapMinimize functionaliteit eerst te proberen voordat je definitief een out-of-memory gooit.
Ik denk dat je hier op het verkeerde spoor zit.
Uniformiteit in je exceptions bereik je door te deriven van de standaard exceptions, daar zijn ze voor gemaakt.
Je eigen memory manager kun je gewoon met de standaard new
laten samen werken, via set_new_handler. En die kan ook HeapMinimize() proberen.

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 woensdag 23 januari 2002 09:22 schreef MSalters het volgende:
:? Ik heb geen idee. Omdat je denkt dat ze beter zijn, maar waarom denk je dat dit soort handle classes beter is dan direct containment? Wat zijn de technische voordelen?
Ah ik snap nu eindelijk waar de discussie scheef ging... jij vroeg "Waarom denk je dat Reference classes beter zijn dan direct containment zoals vector<> doet ?" wat ik als retorisch opnam, en daardoor raakte ik de draad een beetje kwijt. :)

De technische voordelen van reference classes zijn vrij duidelijk, de nadelen ook. Ik heb ze hier al eens opgeschreven. Deel 2 van de tutorial is er nooit van gekomen uit lammigheid :)
Ik denk dat je hier op het verkeerde spoor zit.
Uniformiteit in je exceptions bereik je door te deriven van de standaard exceptions, daar zijn ze voor gemaakt.
Je eigen memory manager kun je gewoon met de standaard new
laten samen werken, via set_new_handler. En die kan ook HeapMinimize() proberen.
Ik doe niets volgens de standard C++ library. Het ding gebruiken is een optie, geen verplichting (en dat is waar jij op het verkeerde spoor zit). Waarom zou ik moeten deriven van de standaard exceptions als ik zelf een betere, duidelijke, effectievere, en uniformere exception-hierarchie op kan zetten? Beetje pointless... :Z

Set_new_handler is waardeloos omdat je er alleen de globale new-handler mee vervangt. Echt OOP-design vereist dat je binnen de base-class van je framework de new-operator op class-level overload zodat je geen conflicten krijgt met andere frameworks en/of omgevingen.

Maar dit hoef ik jou als 'ITer' (volgens je profile) toch niet uit te leggen? :*

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 23:11
Op vrijdag 25 januari 2002 00:12 schreef curry684 het volgende:
Ik doe niets volgens de standard C++ library. Het ding gebruiken is een optie, geen verplichting (en dat is waar jij op het verkeerde spoor zit). Waarom zou ik moeten deriven van de standaard exceptions als ik zelf een betere, duidelijke, effectievere, en uniformere exception-hierarchie op kan zetten? Beetje pointless... :Z
Of het een optie is, of een verplichting, dat varieert van project tot project. Sinds vorige week is het voor mij & m'n collegas een verplichting.
De belangrijkste reden waarom je niet je eigen wiel moet uitvinden is omdat je toekomstige opvolgers in boeken/cursussen/etc. de standaard manier hebben gezien.
En omdat er een standaard exception hierarchie is mag je verwachten dat compilers daar tenminste net zo efficient mee omgaan als met jouw exceptions.
Set_new_handler is waardeloos omdat je er alleen de globale new-handler mee vervangt. Echt OOP-design vereist dat je binnen de base-class van je framework de new-operator op class-level overload zodat je geen conflicten krijgt met andere frameworks en/of omgevingen.
Vervangen is maar een oplossing. Chainen is een andere oplossing. ( Met excuses aan ZKH WA :) )
Maar wat class-specific operator new heb je wel gelijk.

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