|
| includes go round and round Fra : Peter CC |
Dato : 03-01-03 13:20 |
|
Jeg har en lidt dum situation hvor jeg har to typer objekter som begge har
pointere til den anden type i sig. Hvert objekt er i seperat cpp+h filer.
headerA:
#ifndef HEADERA
#define HEADERA
#include HEADERB
class ObjA
{
ObjB *_pObjB;
.....
};
#endif
-------------------
headerB:
#ifndef HEADERB
#define HEADERB
#include HEADERA
class ObjB
{
ObjA *_pObjA;
.....
};
#endif
det virker bare ikke, da headerA definer HEADERA og inkluderer headerB. B
vil så include A for definition på hvad ObjA er, men da HEADERA er definet,
så bliver den header ikke includet alligevel. og der vil være en fejl med
udefineret type for ObjA *_pObjA
Spørgsmålet, efter denne lange udredning, går så på hvordan man vil fikse
det. Begge objekterne skal have pointers til den anden type, så det skal
forblive sådan... men er den eneste løsning at istedet for includes at bare
skrive sådan her;
headerB:
#ifndef HEADERB
#define HEADERB
class ObjA; ////#include HEADERA droppe includen
class ObjB
{
ObjA *_pObjA;
.....
};
#endif
Nu kan det jo compile..det virker bare lidt lappeagtigt.
| |
Igor V. Rafienko (03-01-2003)
| Kommentar Fra : Igor V. Rafienko |
Dato : 03-01-03 14:40 |
|
[ Peter CC ]
[ ... ]
> Spørgsmålet, efter denne lange udredning, går så på hvordan man vil
> fikse det.
Forward declaration. Det er ikke pent, men det virker:
headerA.h:
----------
#ifndef AHEADER_
#define AHEADER_
class B;
class A
{
/* class body */
};
#endif
headerB.h:
----------
#ifndef BHEADER_
#define BHEADER_
#include "headerA.h"
class B
{
/* class body */
};
#endif
Man kan sikkert ha en forward declaration i begge tilfellene (eller,
dersom du ikke gjør noe annet enn å deklarere en peker til den
aktuelle klassen, så kan du sikkert ha en forward declaration i begge
tilfellene. Den (deklarasjonen) forteller nemlig ikke noe mer enn at
typen finnes).
[ ... ]
> Nu kan det jo compile..det virker bare lidt lappeagtigt.
Nettopp. Forover referanser er en God Ting[tm]
ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
-- pederst på irc
| |
Mads Orbesen Troest (03-01-2003)
| Kommentar Fra : Mads Orbesen Troest |
Dato : 03-01-03 17:38 |
|
Hej;
> class ObjA; ////#include HEADERA droppe includen
> Nu kan det jo compile..det virker bare lidt lappeagtigt.
Lappeagtigt? Du skal ALTID søge at minimere behovet for at include andre
klassers deklarationer, og istedet anvende forward declarations, så længe
det kun er pointere/referencer til andre klasser du har brug for. Altså
netop hvad du har gjort - du bør bare gøre det i A også.
Grunden er, at man meget gerne vil minimere de ellers hurtige (i større
projekter især) vildt forgrenede (og helt overdrevne) file-dependencies der
opstår. Når du så retter i én header fil er der pludselig (med et
traditionelt build-system; der findes systemer der er smartere og kigger
"dybere" end de overfladiske og typisk overdrevne include-afhængigheder) 500
"afhængige" filer der bliver rekompileret og det tager et år, selv om der
kun anvendes "anonyme" pointere/referencer, der kunne have være klaret med
forward declarations.
Som Igor også skriver: "Forover referanser er en God Ting[tm]"! :)
/\/\\ads Orbesen Troest
| |
Troels Thomsen (06-01-2003)
| Kommentar Fra : Troels Thomsen |
Dato : 06-01-03 12:49 |
|
> Lappeagtigt? Du skal ALTID søge at minimere behovet for at include andre
> klassers deklarationer, og istedet anvende forward declarations, så længe
> det kun er pointere/referencer til andre klasser du har brug for.
Hvordan gør man det bedst i praksis ?
Laver man en
headerA.h
og
headerAforward.h
og så inkluderer man sidsnævnte alle de steder man kan komme af sted med det
?
| |
WarSnail (06-01-2003)
| Kommentar Fra : WarSnail |
Dato : 06-01-03 22:23 |
|
> Hvordan gør man det bedst i praksis ?
> Laver man en
> headerA.h
> og
> headerAforward.h
>
> og så inkluderer man sidsnævnte alle de steder man kan komme af sted med
det
istedet for at include headerA.h hvori klassen A er defineret, så skriver
du...
-------------
class A; ////istedet for #include "headerA.h"
class B
{
A* _pA;
......
};
--------------
så kan det fungere. i den fil hvor du implementere klasseB, der skal du dog
include headerA hvis du bruger noget i den..alla
_pA->Paint(dc); eller ligende, men det er ikke et problem da du i reglen
ikke includer dine implementeringsfiler (*.cpp ex) i andre.
| |
|
|