PDA

Visualizza la versione completa : [C++] Sorgente diviso in + file


iguana13
03-03-2004, 20:32
Non è la prima volta che mi capita questo problema, ma ora mi è necessario risolverlo!
Il tutto è comunciato quando, nello sviluppo di una classe, il codice è diventato lungo, complesso e difficile da gestire. Quindi ho deciso di dividerlo in + file.

La classe in questione si occupa del persing e risoluzione di un'espressione algebrica.

E' strutturato in questo modo:

tree.cpp
Contiene la struttura dell'albero binario utilizzato.

parser.cpp
Contiene tutti i prototipi delle funzioni e della classe.

I corpi delle funzioni sono divisi in varie classi, come solve.cpp, parsing.cpp, research.cpp & co.

Ho strutturato parser.cpp (che sarebbe l'unico header da includere per poter utilizzare la classe) in questo modo:




// Struttura dell'albero
#include "tree.cpp"

// Definizione classe
class parser {
// Prototipi delle funzioni
...
public:
...
};

// corpo delle funzioni
#include "parsing.cpp"
#include "solving.cpp"
#include "research.cpp"

// Fine


Provo a compilare con il VC++ 6 e segna 99 (poi dopo poche modifiche 280 :stordita: ) errori.

Come devo strutturare i file? :cry: :dhò:

Heeelppp!!!
Aiuuuuuuutooooo!!!!! :dhò:

GNAWS
03-03-2004, 20:57
Uhm... Se puoi usare il gcc (col visual c++ non ho idea di come si faccia :bhò: ) basta che compili i files uno per volta con l'opzione -c. Esempio:
gcc -o file.obj -c file.cpp
dopo di che unisci tutti i files in uno unico così:
gcc nome_primo_file.obj nome_secondo_file.obj -o binario_finale

internet
04-03-2004, 01:44
Originariamente inviato da iguana13


Provo a compilare con il VC++ 6 e segna 99 (poi dopo poche modifiche 280 :stordita: ) errori.

Come devo strutturare i file? :cry: :dhò:

Heeelppp!!!
Aiuuuuuuutooooo!!!!! :dhò:

postane una decina almeno si capisce qualcosa di più


come farei io la struttura

file parser.h


#ifndef __PARSER_H__
#define __PARSER_H__

risoluzione dipendenze

// Definizione classe
class parser {
// Prototipi delle funzioni
...
public:
...
};

#endif // __PARSER_H__


risoluzione dipendenze

a) tramite #include "tree.h"

oppure

b) tramite forward declaration (fortemente consigliata)
class tree;

file parser.cpp


// Struttura dell'albero
#include "parser.h"

definizione metodi della classe parser


le direttive #ifndef servono ad evitare le ridefinizioni multiple

infatti è possibile fare più dichiarazioni, ma non più di 1 definizione altrimenti il compilatore :nonlodire. :)
perchè non saprebbe quale definizione scegliere.

es:
class tree;
class tree;

sono 2 dichiarazioni, quindi no problema


int i;
int i;

sono 2 definizioni, quindi guai


potrebbe andare bene questa a patto che utilizzi la classe tree tramite puntatori o tramite reference



#ifndef __PARSER_H__
#define __PARSER_H__

class tree;

// Definizione classe
class parser {
tree* my_tree;
// Prototipi delle funzioni
...
public:
};

#endif // __PARSER_H__


altrimenti



#ifndef __PARSER_H__
#define __PARSER_H__

#include "tree.h"

// Definizione classe
class parser {
tree my_tree;
// Prototipi delle funzioni
...
public:

};

#endif // __PARSER_H__



comunque ti consiglio ti partire prima da qui
http://www.nbirn.net/Resources/Developers/Conventions/Style/C_Includes.htm
http://dit.unitn.it/~dandrea/progogg/lucidi/07_Class.pdf
http://netalab8.di.univaq.it/so/stuff/linguaggio_c.pdf


guarda anche nel thinking in c++ di bruce eckel liberamente scaricabile dal suo sito.

iguana13
04-03-2004, 15:35
Innanzitutto grazie per la risposta. :)

Ora sto cercando di fare qualcosa, ma prima qualche domanda:

- Nel tuo codice, in parser.h non ci sono istruzioni #include per files come parser.cpp, con il corpo delle funzioni. Lo devo mettere? Se no, come fa il compilatore a sapere di includere quei file?

- In un file con il corpo delle funzioni come parser.cpp, trovo #include "parser.h", ma il preprocessore troverà già definita la macro __PARSER_H__ e quindi non dovrebbe ignorare #include "tree.h" ?

Grazie 1K :ciauz:

internet
04-03-2004, 16:58
Originariamente inviato da iguana13
Innanzitutto grazie per la risposta. :)

- Nel tuo codice, in parser.h non ci sono istruzioni #include per files come parser.cpp, con il corpo delle funzioni. Lo devo mettere? Se no, come fa il compilatore a sapere di includere quei file?

dipende da come la classe parser utilizza gli oggetti delle classi da cui dipende.

se utilizzi gli oggetti per reference o tramite puntatori l'unica cosa di cui il compilatore ha bisogno è una forward diclaration (ripeto è fortemente consigliata perchè nel momento in cui lavorerai in grossi progetti, all'atto di modificare la classe da cui dipendi dovrai ricompilare solo questa, e se il progetto è grosso risparmi anche ore di compilazione).

esempio di forward declaration

class tree;

dovrei vedere il codice di parser.h per capire se puoi utilizzare semplicemente una forward declaration oppure una include.



- In un file con il corpo delle funzioni come parser.cpp, trovo #include "parser.h", ma il preprocessore troverà già definita la macro __PARSER_H__ e quindi non dovrebbe ignorare #include "tree.h" ?

Grazie 1K :ciauz:

No, #ifndef dice
se non è definita __PARSER_H__ allora definisci __PARSER_H__ e includi solo la prima volta il file parser.h con essa includi la prima volta il file tree.h.

differenza tra dichiarazione e definizione (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_pluslang_c.2b2b_.declarations_and_definitions.asp )
differenza tra dichiarazione e definizione 2° link (http://infocom.cqu.edu.au/Staff/Mike_Turnbull/Home_Page/Lecturetts/Sect9.htm)

sei in visual c++ quindi devi aggiungere al progetto i file *.cpp che definiscono le classi, questo permetterà al linker di trovare le definizioni dei simboli che hai dichiarato negli header files.

Gli errori "undefined reference" sono errori della fase di linking, comunque nei link del messaggio precedente è descritta anche questa fase.

Se il codice è troppo lungo e se vuoi puoi postarmeli in privato.

iguana13
04-03-2004, 19:25
Si vede che sono rimasto troppo attaccato al vecchio concetto che dice che includere un file sia come ricopiarlo all'interno, ma evidentemente non è così.

Come hai detto tu, sarà il linker a preoccuparsi di trovare il corpo delle funzioni.

Ora vedo se riesco a sistemare... :master: :ciauz:

Loading