• 8 odgovora
  • 4.081 pregleda
Rekurzivno #include-ovanje 22.02.2005. u 01:32 · pre 263 meseci #1
Najbolje ce biti jasno sta je problem na primeru.

Code:

// boot.h

#ifndef __BOOT_HEADER__
#define __BOOT_HEADER__ 

#include "global.h"

namespace boot {
  /* ovde dodju klase koje koriste kod iz global.h */
  /* .... */
}

#endif


Code:

// global.h

#ifndef __GLOBAL_HEADER__
#define __GLOBAL_HEADER__ 

#include "video.h"
#include "josgomilatoga.h"

namespace glob {
  /* ovde idu klase koje koriste video.h */
  /* .... */
}

#endif


Code:

// video.h

#ifndef __VIDEO_HEADER__
#define __VIDEO_HEADER__ 

#include "boot.h"

namespace video {
  /* ovde dodju klase koje koriste kod iz boot.h i ko zna jos odakle*/
  /* .... */
}

#endif


Naravno, prevodilac (g++) se buni da se iz fajla video.h deklarisu neki tipovi koji nisu clanovi boot namespace-a (iz boot.h), jer boot.h u trenutku prevodjenja fajla video.h prakticno nije jos ni ucitan, vec samo onaj njegov deo do #include "global.h". Namerno sam ubacio ovaj global.h fajl, da bar malo docara kompleksnost, jer imam otprilike 15-ak razlicitih *.h fajlova u ovom projektu i vlada opsti haos po pitanju medjuzavisnosti. Rucno sredjivanje bi bilo veoma cupavo, a ustalom zanima me da li postoji neki finiji nacin da se ovo resi, npr. dobacivanjem posebnih opcija prevodiocu? Fazon je u tome da ce verovatno biti potrebno dodavati jos gomilu podmodula, tj. zasebnih celina, namespace-ova i zaglavlja, pa rucno ne bih bas da radim.

Razmisljao sam da ubacim deklaraciju svih klasa koje se pojavljuju u datom zaglavlju PRE ovih #include poziva, a definicije posle njih. Da li bi ovo pomoglo i da li je uopste neophodno?
Mora da postoji neki automatizovani nacin...
Potpis
why stand on a silent platform?
fight the war... fuck the norm!
Re: Rekurzivno #include-ovanje 24.02.2005. u 00:32 · pre 263 meseci #2
Mislim da je nesto skroz drugo u pitanju, osim ako nisi mozda zaboravio da u nekom fajlu se sa #ifndef ... #define ... #endif "zastitis" od rekurzije. Nesto sam spreman da dam desnu ruku da GCC nece da pravi gore navedeno ako si dobro napisao taj kod...
Potpis
Dejan Lekic
software engineer, MySQL/PgSQL DBA, sysadmin
Re: Rekurzivno #include-ovanje 24.02.2005. u 03:06 · pre 263 meseci #5
Citat:
Najbolje ce biti jasno sta je problem na primeru.
Za vaše čitateljsko zadovoljstvo, destilat gore pomenutog problema i rešenje.

Problem:

Code:
class A {
         B *x;
 };
 
 class B {
          A *y;
 };
 
 int main()
 {
         return 0;
 }
 

Izlaz koji daje prevodilac:

Code:
[email protected]:~
 $ g++ cycle.cc
 cycle.cc:2: error: ISO C++ forbids declaration of `B' with no type
 cycle.cc:2: error: expected `;' before '*' token
 [email protected]:~
 $
 


Rešenje:

Code:
class B;
 
 class A {
         B *x;
 };
 
 class B {
          A *y;
 };
 
 int main()
 {
         return 0;
 }
 

Izlaz koji daje prevodilac:
Code:
[email protected]:~
 $ g++ cycle2.cc
 [email protected]:~
 $
 

Dakle, moraš negde da presečeš krug rekurzivnih definicija kako bi sve klase mogle da budu definisane. Problem kog imaš je isto to, samo u većem izdanju.

f
Re: Rekurzivno #include-ovanje 24.02.2005. u 18:58 · pre 263 meseci #6
Eee, ma znam ja to da se moze deklarisati klasa ispred svega, pa tek posle da je definises. To je elementarno. Ali, ajde probaj da uokviris definiciju svake klase sa zasebnim namespace-om, pa da vidis sta se desava. Probao sam pre definicije klase A (u tvom primeru) da stavim deklaraciju
Code:
class B_namespace::B;

ali nista od toga. Deklaracija namespace-a kao
Code:
namespace B_namespace;

pre definicije klase A (i njenog namespace-a) takodje ne radi.
Ako stavim
Code:
class B;

pre svega toga, to onda naravno definise klasu B kao clanicu globalnog namespace-a, i koristi nju unutar klase A.


??? :)
Potpis
why stand on a silent platform?
fight the war... fuck the norm!
Re: Rekurzivno #include-ovanje 24.02.2005. u 19:27 · pre 263 meseci #8
Evo par sekundi posle slanja mi je sinulo resenje. Kod koji ne radi:
Code:

namespace A_namespace { 
class A {
    B_namespace::B *x;
};
}

namespace B_namespace {
class B {
    A_namespace::A *y;
};
}

int main()
{
    return 0;
}


A evo kako treba:

Code:

namespace B_namespace { 
class B;
}

namespace A_namespace { 
class A {
    B_namespace::B *x;
};
}

namespace B_namespace {
class B {
    A_namespace::A *y;
};
}

int main()
{
    return 0;
}


Nasao sam na ovoj stranici da namespace-ovi mogu da se zadaju iz delova. Prema tome, treba definisati B-ov namespace, u njemu dati deklaraciju klase B, i posle je sve kul. Moracu znaci ovo da dodam u svaki fajl... Nije strasno.
U svakom slucaju hvala na pomoci Filipe :)
Potpis
why stand on a silent platform?
fight the war... fuck the norm!
Prijavite se da biste odgovorili u ovoj temi.PrijavaRegistracija

Premeštanje teme