Newsgroup: it.comp.lang.c++
Titolo: Include Circolari (circular include hell)

 
Sono finito nell'inferno degli include!!!!!
Ho trovato questo "tutorial" e pare funzionare:
http://www.gamedev.net/topic/385203-circular-include-hell-c/
 
 
Tuttavia noto che cio' porta a usare l'allocazione dinamica (cioè le
new() e delete) anzichè la comodissima e praticissima allocazione
statica.
Non esiste un modo per mettere ordine nella giungla degli #include
continuando a usare l'allocazione statica?
 
 
Già che ci siamo, parliamo di semafori: se io ne metto uno dentro a un
oggetto per proteggere l'accesso a... qualunque cosa...tipo un db,
ogni istanza della classe avrà il suo semaforo quindi non serve a un
cassss...!
Il semaforo DEVE essere condiviso!
La soluzione potrebbe essere: fare un semaforo statico???  In questo
modo sarebbe unico per tutte le istanze.
No?
 
Marco
 
 

 modo sarebbe unico per tutte le istanze.
 
Ha senso mettere un semaforo in un oggetto per proteggere l'accesso a 
tale oggetto, o a un altro oggetto posseduto da tale oggetto. Se il tuo 
oggetto gestisce un database, e hai cento oggetti e altrettanti 
database, ci vogliono cento semafori.
Ma se ha uno solo database acceduto da cento oggetti, e vuoi proteggere 
l'accesso a tale database, allora ci vuole un solo semaforo, e quindi 
non lo devi mettere in tali oggetti.
Lo puoi mettere come membro statico della classe di tali oggetti, oppure 
da qualche altra parte.
 
-- 
 
Carlo Milanesi
http://carlomilanesi.wordpress.com/
 

Effettivamente queste cose si verificano quando il codice è
incasinato.
Però la maledizione degli #include è abbastanza inevitabile quando il
codice inizia a essere di buone dimensioni a seguito di continue
aggiunte nel tempo (chi non c'è mai passato?).
 
La questione del semaforo è una vaccata totale, sì!  E' venuta cosi' a
seguito di "paletti" che mi sono sono stati comunicati solo in seguito
(cioe' all'improvviso m'hanno cambiato le carte in tavola)...e
ormai...rifare tutto non mi va.
Alla fine faccio che la risorsa condivisa deve condividere anche il
semafaro.
 
Marco

 Carlo Milanesihttp://
carlomilanesi.wordpress.com/
 
 
A proposito di include circolari. Lo ammetto sono un po' newbie ma la
mia perplessità è questa:
Prendiamo ad esempio un grafo modellato nel modo seguente:
Definiamo un Vertice che al suo interno possiede una lista di archi,
quindi include la definizione dell'oggetto Arco.
Ma all'interno dell'oggetto Arco, per tener traccia dei "terminali",
includo due oggetti di tipo Vertice.
 
In questo caso cado nell'include circolare. Posso risolverlo con una
forward declaration? Poi ho problemi di scope o ridefinizioni delle
classi? a vostro avviso esistono soluzioni più eleganti?

 a vostro avviso esistono soluzioni più eleganti?
 
no, se effettivamente devi gestire le circular references. E 
talvolta non le puoi evitare in modo piu' elegante di questa 
soluzione
 
ciao
Soviet
 

 classi? a vostro avviso esistono soluzioni più eleganti?
 
Direi che occorre fare il seguente ragionamento.
Un vertice e' di proprieta' esclusiva di un arco? Ovviamente no, perche' 
da un vertice possono uscire piu' archi e in un vertice possono entrare 
piu' archi. Quindi necessariamente un arco non puo' contenere vertici, 
ma solo riferimenti a (due) vertici. E questo basta a rompere la 
circolarita' di archi che contengono vertici che contengono archi.
D'altra parte, un arco e' di proprietà esclusiva di un vertice?
In teoria si potrebbe assegnare ogni arco al vertice da cui esce, oppure 
al vertice in cui entra, tuttavia supponendo di assegnarlo al vertice da 
cui esce, si dovrebbe poter scoprire rapidamente quali archi entrano in 
un dato vertice, e questo richiede che ogni vertice, oltre ad avere una 
collezione di archi uscenti posseduto da tale vertice, abbia una 
collezione di riferimenti ad archi entranti, posseduti da un altro vertice.
Quindi è possibile la soluzione in cui ogni vertice contiene gli archi 
che escono da lui e fa riferimento agli archi che entrano in lui, con il 
seguente codice:
 
   struct Vertice;
   struct Arco
   {
     Vertice* inizio;
     Vertice* fine;
   };
   struct Vertice
   {
     vector<Arco> uscenti;
     vector<Arco*> entranti;
   };
 
Tuttavia, mi pare una soluzione poco elegante, e consiglierei invece una 
soluzione in cui i vertici non possiedono nessun arco. Tale soluzione 
puo' essere codificata nel seguente modo:
 
   struct Vertice;
   struct Arco
   {
     Vertice* inizio;
     Vertice* fine;
   };
   struct Vertice
   {
     vector<Arco*> uscenti;
     vector<Arco*> entranti;
   };
 
oppure nel seguente modo:
 
   struct Arco;
   struct Vertice
   {
     vector<Arco*> uscenti;
     vector<Arco*> entranti;
   };
   struct Arco
   {
     Vertice* inizio;
     Vertice* fine;
   };
 
Una volta che hai scelto quale delle tre soluzioni adottare, puoi 
scegliere di mettere il tuo codice in file header, invece di tenere 
tutto in un solo file. Per esempio, nel caso della due ultime soluzioni, 
potrai scrivere:
 
File "Vertice.hpp":
   #ifndef Vertice_hpp
   #define Vertice_hpp
   struct Arco;
   struct Vertice
   {
     vector<Arco*> uscenti;
     vector<Arco*> entranti;
   };
   #endif
 
File "Arco.hpp":
   #ifndef Arco_hpp
   #define Arco_hpp
   struct Vertice;
   struct Arco
   {
     Vertice* inizio;
     Vertice* fine;
   };
   #endif
 
Ovviamente le funzioni membro di "struct Arco" non prenderanno come 
argomenti ne' restituiranno oggetti di tipo Vertice (per valore), ma 
solo puntatori o riferimenti a tali oggetti; analoga considerazione vale 
per le funzioni membro di "struct Vertice".
Inoltre le implementazioni dei metodi di "struct Arco", se poste 
nell'header, non potranno creare sullo stack oggetti di tipo "Vertice", 
e analogamente per "struct Vertice".
