Vraagje OO icm C++ ..

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Topicstarter
Hallo,

Ik heb een vraagbetreft een OO implementatie van een C++ programma.

Gegeven een Base en een Derived klasse. Daarnaast een 'manager' die alleen de Base kent.
Nu wil ik in mijn programma via de 'manager' Base objecten opvragen en die benaderen als Derived (hoe ik weet dat ze van type derived zijn is nu even buiten scope).

Als ik vanuit mijn manager als pointer return en dan (evt dynamic) cast naar Derived, dan bega ik een grove OO violation: een pointer naar een private member, toch?
Als ik ze via een reference return en cast, dan heb ik een onoverzichtelijke, onduidelijke syntax.

Zie ik iets over het hoofd, of is dit gewoon bad design?

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class MyBase
{
  public:
    MyBase();
      
    void set(int x);
    int   get(void);
    
    //...
};

class MyDerived : public MyBase
{
  public:
    MyDerived();
      
   void special(int y);    
    //...
};

class MyManager{     //MyManager kent alleen MyBase  
    
    public:
      MyManager();
      
     MyBase& getObjectByRef(int i) {return *myBases[i];}    //By reference 
     MyBase*  getObjectPtr(int i) {return myBases[i];}          //Pointer

    private:
       MyBase *myBases[10];
}


void main()
{
     MyDerived * derivedObj;
     MyManager * manager = new MyManager();
     
    //optie 1:
    ((MyDerived&)manager->getObjectByRef(0)).special(1);  //goed? lange syntax, onduidelijk dat reference
    
    //optie 2:
    ((MyDerived *) derivedObj = ((MyDerived *) manager->getObject(0));  //fout, OO-wise?
    derivedObj->special(1);   
    derivedObj->special(2);
    derivedObj->special(3);
}

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

als je zeker weet dat de base die je krijgt eigenlijk een derived is, dan kan je hem casten (al dan niet dynamic).
je kan ook je base class een virtual special() geven, en dan overriden in derived, dan kan je je special() aanroepen op de base.

of je een pointer of een reference gebruikt maakt niet uit in dit geval, het gaat hetzelfde uitvoeren, dus het is een kwestie van smaak :) maar een reference casten is net zo "evil" als een pointer casten, dus het 1 is niet beter dan de ander.

-niks-


Acties:
  • 0 Henk 'm!

  • G33rt
  • Registratie: Februari 2002
  • Laatst online: 22-06-2022
C++ kent hier gewoon verschillende smaken casts voor, op de 'C-manier' casten van classes is vrijwel nooit verstandig in zo'n context. Bekijk even een tutorial over casten; verschillende voorbeelden staan bijvoorbeeld hier (inclusief het typische probleem dat jij beschrijft).

[ Voor 8% gewijzigd door G33rt op 09-06-2010 17:00 ]


Acties:
  • 0 Henk 'm!

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

.oisyn

Moderator Devschuur®

Demotivational Speaker

EddoH schreef op woensdag 09 juni 2010 @ 16:40:
Als ik vanuit mijn manager als pointer return en dan (evt dynamic) cast naar Derived, dan bega ik een grove OO violation: een pointer naar een private member, toch?
Het is geen pointer naar een private member - het is een kopie van een private member. Met die pointer kun je de member (de pointer zelf in de class dus) niet aanpassen.

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.


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Topicstarter
Bedankt Voor de replies, even 1 voor 1:
MLM schreef op woensdag 09 juni 2010 @ 16:47:
als je zeker weet dat de base die je krijgt eigenlijk een derived is, dan kan je hem casten (al dan niet dynamic).
je kan ook je base class een virtual special() geven, en dan overriden in derived, dan kan je je special() aanroepen op de base.
Dat van het casten was mijn plan ook :)
Ik wil de base class geen virtuals geven, omdat ik dan bij elke derived class virtual methodes aan Base moet toevoegen..
MLM schreef op woensdag 09 juni 2010 @ 16:47:
of je een pointer of een reference gebruikt maakt niet uit in dit geval, het gaat hetzelfde uitvoeren, dus het is een kwestie van smaak :) maar een reference casten is net zo "evil" als een pointer casten, dus het 1 is niet beter dan de ander.
Ik heb het eigenlijk nooit geprobeerd, maar kan je eigenlijk delete aanroepen of een reference? Daar gaat het me namelijk voornamelijk om(dat dat niet kan). Het is inderdaad zo dat het hoe dan ook niet zo mooi is, vandaar ook dit topic.
G33rt schreef op woensdag 09 juni 2010 @ 16:59:
C++ kent hier gewoon verschillende smaken casts voor, op de 'C-manier' casten van classes is vrijwel nooit verstandig in zo'n context. Bekijk even een tutorial over casten; verschillende voorbeelden staan bijvoorbeeld hier (inclusief het typische probleem dat jij beschrijft).
Bedankt, maar het gaat me eigenlijk niet om het casten maar meer om het design probleem:
ik wil een member van derived aanroepen, zonder alle controle over Derived uit handen te geven. Manager moet alle Derived beheren...
.oisyn schreef op woensdag 09 juni 2010 @ 17:48:
[...]

Het is geen pointer naar een private member - het is een kopie van een private member. Met die pointer kun je de member (de pointer zelf in de class dus) niet aanpassen.
Ik volg je even niet...
Als ik een pointer myBases[i] vanuit Manager return en cast naar een Derived pointer , dan heb ik toch geen kopie van het object waar myBases[i] naar wijst?


Alles samenvattend, ik kom dus niet onder het casten van een pointer uit als ik een method van Derived wil aanroepen?

Acties:
  • 0 Henk 'm!

  • TaraWij
  • Registratie: December 2007
  • Laatst online: 08-02 18:37
Je gebruikt ook te veel haakjes bij optie 2 wat het onoverzichtelijk maakt.
C++:
1
((MyDerived *) derivedObj = ((MyDerived *) manager->getObject(0));

Dit is met het juiste aantal haakjes en een static_cast heel wat netter,
derivedObj is immers ook al gedeclareerd en hoeft dus geen cast in de linkerkant:
C++:
1
derivedObj = static_cast<MyDerived *>(manager->getObject(0));

Pas als je meer dan 80 karakters op een lijn hebt moet je jou zorgen gaan maken over breedte,
om Linus Torvalds maar even te quoten betreffende breedte en indentatie:
Now, some people will claim that having 8-character indentations makes
the code move too far to the right, and makes it hard to read on a
80-character terminal screen. The answer to that is that if you need
more than 3 levels of indentation, you're screwed anyway, and should fix
your program.
Met dat laatste bedoeld hij het gebruik van functies voor diepere scopes.

[ Voor 65% gewijzigd door TaraWij op 09-06-2010 18:34 ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

EddoH schreef op woensdag 09 juni 2010 @ 18:15:
Ik volg je even niet...
Als ik een pointer myBases[i] vanuit Manager return en cast naar een Derived pointer , dan heb ik toch geen kopie van het object waar myBases[i] naar wijst?
Klopt. Je maakt een kopie van de pointer naar het adres waar de waarde staat die jij hebben wil. Bij mijn weten kan en mag dat gewoon, maar mijn C++ kennis is niet meer wat 'ie geweest is. :P

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

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

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het ging niet zozeer om C++, maar om dat een pointer naar een private member natuurlijk wat tegen OO regels van encapsulatie indruist.

Vergelijk:
C++:
1
2
3
4
5
6
7
8
class MyClass
{
public:
    int * Get() { return &myInt; }

private:
    int myInt;
}

Nu kun je de pointer naar myInt opvragen, en dus zo die int aanpassen. Nu gaat het niet om een int, maar om een MyBase*. De class heeft geen MyBase member waar je een pointer naartoe geeft. De class heeft een MyBase* member, en die return je gewoon vanuit de getter, net alsof je een nonpointer type teruggeeft. Waar het om gaat is dat je dus geen pointer naar een private member teruggeeft. Had de TS dat wel gedaan, dan was het returntype een MyBase** (de member is een pointer, dus je krijgt dan een pointer naar een pointer).

Wat dat betreft is er natuurlijk ook geen verschil tussen pointers en references. De code uit mijn vorige voorbeeld met de int had niet netter geweest als het een reference was geweest. Dat impliceert namelijk nog steeds dat je die int mag aanpassen.

[ Voor 13% gewijzigd door .oisyn op 09-06-2010 18:35 ]

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.


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Topicstarter
@.oisyn:
Je hebt natuurlijk gelijk wat betreft de kopie van een member. De kopie is in dit geval de pointer,
ik had niet gelijk door wat je bedoelde. Mijn formulatie is dus inderdaad fout: ik heb een kopie van een private member.

Dit neemt natuurlijk het probleem nog niet weg. Namelijk dat ik geen controle heb over wat er buiten mijn 'Manager' met de pointer gebeurd, hier zou delete op kunnen worden aangeroepen.

In de huidige praktijk is het op zich geen probleem, aangezien ik de software zelf beheer. Maar een fout is zo gemaakt, en ik ben benieuwd hoe jullie een dergelijk ontwerp zouden implementeren, dus zonder de 'vieze' pointer, en zonder dat de manager weet met welke derived klasse hij te maken heeft.

Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Topicstarter
Voor diegene die geinterreseerd zijn.
Ik heb het geimplementeerd m.b.v. shared pointers, om nog een zekere veiligheid te garanderen.
De objecten waar de pointers in de Manager naar wijzen, kunnen zo in ieder geval nooit door een 3e worden gedelete, zonder dat de manager er nog reference naar heeft.

Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
Return een const reference dan geef je aan de gebruiker van je manager door dat hij dit object niet zou mogen veranderen. Als je weet welk type je trg wilt hebben zou je ook een template functie kunnen maken die een const T& trge geeft

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyManager{     //MyManager kent alleen MyBase   
     
    public: 
      MyManager(); 
       
     MyBase& getObjectByRef(int i) {return *myBases[i];}    //By reference  
     MyBase*  getObjectPtr(int i) {return myBases[i];}          //Pointer 

    template<class T>
    const T& getObject(int i) { return (T)myBases[i]; }

    private: 
       MyBase *myBases[10]; 
} 


Op die manier is de class cast in de manager en kan je eventueel meer checks doen zodat een gebruiker nooit een object probeert te casten naar iets wat niet goed is.

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


Acties:
  • 0 Henk 'm!

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

.oisyn

Moderator Devschuur®

Demotivational Speaker

EddoH schreef op woensdag 09 juni 2010 @ 20:08:
Dit neemt natuurlijk het probleem nog niet weg. Namelijk dat ik geen controle heb over wat er buiten mijn 'Manager' met de pointer gebeurd, hier zou delete op kunnen worden aangeroepen.
Dat is met een reference niet anders. Een pointer impliceert niet dat het object met 'new' is aangemaakt, net zoals een reference niet impliceert dat het object een member is van iets of op de stack staat.

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.


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Topicstarter
NC83 schreef op donderdag 10 juni 2010 @ 14:29:
Return een const reference dan geef je aan de gebruiker van je manager door dat hij dit object niet zou mogen veranderen. Als je weet welk type je trg wilt hebben zou je ook een template functie kunnen maken die een const T& trge geeft

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyManager{     //MyManager kent alleen MyBase   
     
    public: 
      MyManager(); 
       
     MyBase& getObjectByRef(int i) {return *myBases[i];}    //By reference  
     MyBase*  getObjectPtr(int i) {return myBases[i];}          //Pointer 

    template<class T>
    const T& getObject(int i) { return (T)myBases[i]; }

    private: 
       MyBase *myBases[10]; 
} 


Op die manier is de class cast in de manager en kan je eventueel meer checks doen zodat een gebruiker nooit een object probeert te casten naar iets wat niet goed is.
Interresante suggestie. Is alleen lichtelijk irritant dat er altijd een cast bij de call moet. Maar das mierenn*ken ;)
.oisyn schreef op donderdag 10 juni 2010 @ 15:03:
[...]

Dat is met een reference niet anders. Een pointer impliceert niet dat het object met 'new' is aangemaakt, net zoals een reference niet impliceert dat het object een member is van iets of op de stack staat.
Heb je natuurlijk gelijk in.

[ Voor 3% gewijzigd door EddoH op 10-06-2010 16:21 ]


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 15:26
Wat is eigenlijk de reden dat je ze als derived wilt benaderen? Kan je dat niet oplossen met een virtual functie oid?

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


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Topicstarter
EddoH schreef op woensdag 09 juni 2010 @ 18:15:

Ik wil de base class geen virtuals geven, omdat ik dan bij elke derived class virtual methodes aan Base moet toevoegen..
Er kunnen oneindig veel veschillende derived classes zijn, die allemaal andere functies hebben, not done om voor elke verschillende functie een virtual in de base te gaan implementeren...

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

maar het is niet "not done" om voor alle van de oneindig veel derived classes een dynamic_cast te doen om uit te vinden welke het is?

ik ben benieuwd in wat voor OO architectuur je een oneindig aantal derived classes kunt hebben, en die allemaal een specifiek code-path te geven (gezien die casts), of als je altijd zeker weet dat je functie slechts met 1 van de derived class-types aangeroepen word, wat is dan het nut van die oneindig aantal derived classes :P

[ Voor 21% gewijzigd door MLM op 11-06-2010 11:50 ]

-niks-


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Topicstarter
Ik geef toe dat het gebruik van 'oneindig veel' wat overdreven is, maar ik weet op dit moment nog niet hoeveel verschillende derived classes er zullen komen, maar wel dat er veel verschillende zullen zijn :P

Er wordt niet met dynamic_cast uitgezocht welke klasse de derived is. Dit is van tevoren bekend als hij wordt opgevraagd.

Om even de use-case te schetsen:
Het gaat hier om een temperatuur regelsysteem(thermostaat - achtig).
De kernfunctionaliteit is hetzelfde: er is een ingestelde temperatuur. De manager zorgt dat de ingestelde temperatuur wordt gecommuniceerd naar de besturingslaag van de verwarming.
Er zijn echter verschillende thermostaatfunctionaliteiten: een simpele handbediening, nachtmodussen, timers afhankelijk van de dag van de week, weekkalenders, jaarmodussen, insteltemperatuur afhankelijk van externe factoren, etc etc.

De gui's voor deze thermosstaatmodulen weten welk type ze verwachten. Die pakken dus uit de manager de thermosstaatmodule van het type die ze willen, en roepen daar de benodigde functies op aan. De thermostaatmodule gaat met deze instellingen aan de gang en komt uit op een ingestelde temperatuur. De manager leest deze van de thermostaatmodule ..etc etc.
Er kunnen nu oneindig veel modules toegevoegd worden zonder dat de manager hoeft worden aangepast. Die gebruikt alleen de base

Ik had ook iedere module een interface naar de Manager kunnen geven, maar dan heeft de manager minder controle over de verschillende modules, en kunnen 2 modules tegelijk actief zijn en dergelijke.

Misschien is m'n aanpak hier wel niet optimaal hoor, en dan hoor ik het graag, ik stel een vraag het er van te leren..

Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

EddoH schreef op vrijdag 11 juni 2010 @ 10:51:
[...]


Er kunnen oneindig veel veschillende derived classes zijn, die allemaal andere functies hebben, not done om voor elke verschillende functie een virtual in de base te gaan implementeren...
Misschien hebben je classes dan helemaal niets gemeen en moeten ze helemaal niet afleiden van een gemeenschappelijke base.

Je probeert toch geen CObject-achtig iets te maken (zoals java/python/C# en andere een object class hebben).
CObject is bad, mmkeey. Ik meen ooit eens een artikel gelezen te hebben die het haarfijn uitlegt, maar ik vind het even niet terug.

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
Als je weet welke type ze zijn dan werkt die template methode heel erg makkelijk het is misschien niet de beste oplossing maar het werkt en je weet at compile time of er fouten zijn.

Hoeveel weet de manager van de verschillende modules af?

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Topicstarter
Edit: Op de template manier moet ik natuurlijk steeds een copy constructor voor een Derived in de base maken.....

Maargoed, het returnen van een pointer kan natuurlijk op die manier wel goed, en is ook de enige efficiente manier als ik gewoon bij de data van Derived wil kunnen komen.

[ Voor 70% gewijzigd door EddoH op 11-06-2010 16:08 ]


Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
Je hebt geen copy constructor nodig hoor zolang je pointers naar base opslaat en daarin derived classe met new aanmaakt moet dat gewoon werken.

Een reference is gewoon een pointer type dat nooit null kan zijn vandaar dat je ook een . kunt gebruiken.
Hier een voorbeeld:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Base
{
public :
    Base() {}
    ~Base() {}
};

class Derived : public Base
{
public:
    Derived() {}
    ~Derived() {}
};

Base* variable;

template<class T>
const T& castObject()
{
    return *((T*)variable);
}



int _tmain(int argc, _TCHAR* argv[])
{
    variable = new Derived();

    Derived derived = castObject<Derived>();

    delete variable;
    return 0;
}

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

NC83 schreef op vrijdag 11 juni 2010 @ 19:04:
Een reference is gewoon een pointer type dat nooit null kan zijn vandaar dat je ook een . kunt gebruiken.
Hier een voorbeeld:
Oh really?
C++:
1
2
3
4
5
6
7
8
void foo(int& x)
{
  std::cout << &x << std::endl
  x = 10;
}

int* ptr = NULL;
foo(*ptr);

Dit crasht met VS2008 toch echt op de assignment van x

[ Voor 7% gewijzigd door H!GHGuY op 12-06-2010 12:00 ]

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • TaraWij
  • Registratie: December 2007
  • Laatst online: 08-02 18:37
NC83 schreef op vrijdag 11 juni 2010 @ 19:04:
Een reference is gewoon een pointer type dat nooit null kan zijn vandaar dat je ook een . kunt gebruiken.
Een referentie is helemaal geen pointer type, het is inderdaad wel een verwijzing maar je zal deze verwijzing zelf niet kunnen wijzigen zoals je dat bij pointers kan. Een referentie kan men zien als op compileer tijd een alias voor een variabele te maken, daarentegen weet de compiler op compileer tijd nog niet naar waar een pointer verwijst vandaar dat die ook mogelijk 0 kan zijn omdat die nog nergens naar verwijst. Dit is ook de reden dat je een referentie direct kan gebruiken en een pointer niet.

Zie ook http://www.parashift.com/c++-faq-lite/references.html

[ Voor 4% gewijzigd door TaraWij op 12-06-2010 12:22 ]


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

H!GHGuY schreef op zaterdag 12 juni 2010 @ 12:00:
[...]


Oh really?
C++:
1
2
3
4
5
6
7
8
void foo(int& x)
{
  std::cout << &x << std::endl
  x = 10;
}

int* ptr = NULL;
foo(*ptr);

Dit crasht met VS2008 toch echt op de assignment van x
Je programma is dan ook niet correct volgens de C++ standaard, dus dan mag het crashen :)
Immers, je dereferenced een null-pointer op regel 8 :)

C++ Standaard, 8.3.2.5 bevat zelfs een speciale noot
A reference shall be initialized to refer to a valid object
or function. [ Note: in particular, a null reference cannot exist in a well-defined program, because the only
way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer,
which causes undefined behavior.

[ Voor 5% gewijzigd door MLM op 12-06-2010 17:48 ]

-niks-


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Het verschil dus tussen NULL kunnen zijn en NULL mogen zijn ;)

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Topicstarter
Blijft leuk, C++ :+

Bedankt allemaal voor de suggesties. Het werkt intussen allemaal prima.

Acties:
  • 0 Henk 'm!

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

.oisyn

Moderator Devschuur®

Demotivational Speaker

H!GHGuY schreef op zaterdag 12 juni 2010 @ 12:00:
[...]


Oh really?
C++:
1
2
3
4
5
6
7
8
void foo(int& x)
{
  std::cout << &x << std::endl
  x = 10;
}

int* ptr = NULL;
foo(*ptr);

Dit crasht met VS2008 toch echt op de assignment van x
Een reference kan nooit null zijn. De fout zit al op regel 8, vóór het aanroepen van foo(). Het dereferencen van een null pointer is undefined behaviour. Dat je code pas later crasht doet er niet toe.

Dat je geen rekening hoeft te houden met null references blijkt op sommige compilers tijdens het static_casten waarbij het adres iets opgeschoven dient te worden. Voor een pointer is een null check nodig. Voor een reference niet (en resulteert de pointer arithmetic bijv. in een reference naar adres 0x4)

.edit: moet eerst verder lezen...

[ Voor 36% gewijzigd door .oisyn op 13-06-2010 18:26 ]

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.

Pagina: 1