2017-07-14 2 views
0

Un de mes devoirs implique trois fichiers: LineType.h, LineType.cpp et Driver.cpp. Driver.cpp contient la méthode main() qui utilise une classe définie par LineType.h et LineType.cpp.Quand dois-je # inclure les fichiers .cpp?

Sur mon système, Driver.cpp commence par:

#include "LineType.h" 
#include "LineType.cpp" 
#include <iostream> 

Et le programme fonctionne parfaitement et compile quand je lance g++ Driver.cpp à partir du répertoire de projet via la ligne de commande. Cependant, lorsque mon instructeur tente de compiler le programme (je crois qu'il utilise Eclipse), il ne compile pas. Après quelques va-et-vient, elle a pu résoudre le problème sur son extrémité en commentant l'un des #includes de Driver.cpp:

#include "LineType.h" 
//#include "LineType.cpp" 
#include <iostream> 

Lorsque je tente d'exécuter g++ Driver.cpp sur ce fichier modifié, mon Le compilateur se plaint de "symboles non définis pour l'architecture", ce que je comprends pour signifier qu'il ne peut pas trouver de définitions pour la classe/méthodes étant appelé.

Qu'est-ce que mon instructeur et moi faisons différemment pour causer cette différence de comportement? Pourquoi une ligne requise par mon compilateur fait-elle échouer son compilateur?

+7

Les débutants ne doivent * jamais * inclure les fichiers source. Au lieu de cela, vous devriez lire sur * compilation * et * fichiers séparés * et * liaison *. –

+1

Vous ne devez jamais "# inclure" un fichier cpp. – Justin

Répondre

3

En utilisant #include somefilename signifie que le contenu de somefilename est mis en place de l'inclure.
En mettant #include "LineType.cpp" dans votre fichier Driver.cpp vous avez effectivement mis everythig dans un fichier, puis la compilation en utilisant g++ Driver.cpp fonctionne très bien pour vous.
Lorsque votre instructeur a utilisé IDE pour la compilation, il est passé à une compilation et une liaison séparées. Donc, il a compilé Driver.cpp et LineType.cpp Les deux fichiers contiennent des définitions de LineType.cpp en raison de cette inclusion. Donc, quand il s'agissait de créer des liens, elle avait tout défié dans LineType.cpp à deux reprises et linker ne savait pas quoi faire. Vous pouvez compiler et lier plusieurs fichiers à la fois en utilisant

g++ Driver.cpp LineType.cpp 

ou à l'aide de la compilation séparée et reliant les commandes

g++ -c Driver.cpp 
g++ -c LineType.cpp 

qui va générer des fichiers Driver.o et LineType.o. Ensuite, vous pouvez les combiner en exécutant

g++ Driver.o LineType.o 
6

Vous devez jamais inclure les fichiers source directement.

Au lieu de cela, vous devez lister tous vos fichiers source dans la commande g++ lorsque vous compilez:

g++ Driver.cpp LineType.cpp MyOtherFile.cpp # etc... 
+2

Pour le débutant paresseux, utilisez 'g ++ * .cpp' et vous obtiendrez chaque fichier cpp dans le répertoire. – Justin

1

Personnellement, je recommande vivement ne pas include fichiers source. Mais l'auteur de cette article affirme que l'inclusion de fichiers source peut réduire le temps de compilation de grands projets dans les commandes. Il appelle cela «l'unité construit» et affirme que cette approche est largement utilisée dans l'industrie des jeux. L'idée principale de la construction de l'unité est de réduire le nombre de modules dans une compilation. Comme ceci:

my_unity_build_1.cpp: 

#include "renderer.cpp" 
#include "ui_elements.cpp" 
#include "gameplay_code.cpp" 
#include "character_AI.cpp" 

my_unity_build_2.cpp: 

#include "file_io.cpp" 
#include "cat_dynamics.cpp" 
#include "wobbly_bits.cpp" 
#include "death_ray.cpp" 

Moins de modules signifie moins de fonctions communes de duplication et moins de génération de code. Modules permettent de réduire considérablement le temps de compilation mais ne sont toujours pas standard.

+0

Il y a une certaine quantité de (umm) religion parmi les programmeurs de jeu (comme n'importe quel autre groupe). Il y a souvent de la vérité derrière la religion, mais aussi une acceptation excessive du dogme. Par exemple, préférer des reconstructions complètes sur des générations incrémentielles ou des en-têtes complexes (par exemple, avec l'instanciation de modèle) incluses dans plusieurs unités de compilation augmente les temps de construction totaux (non incrémentiels). On prétend parfois que l'unité construit aide les optimiseurs du compilateur, mais cet argument est affaibli par les chaînes d'outils modernes qui prennent en charge l'optimisation du temps de liaison. – Peter