2009-05-17 2 views
1

Becase Je l'ai vu (et utilisé) des situations comme celle-ci:Que se passe-t-il si plus d'un fichier .cpp est #include?

En header.h:

class point 
{ 
public: 
    point(xpos, ypos); 
    int x; 
    int y; 
}; 

En def.cpp:

#include"header.h" 
point::point(xpos, ypos) 
{ 
    x = xpos; 
    y = ypos; 
} 

En main.cpp:

#include"header.h" 
int main() 
{ 
    point p1(5,6); 
    return 0; 
} 

Je sais que le programme est exécuté depuis principal, mais comment le compilateur sait ce que orde r compiler les fichiers .cpp? (Particulièrement s'il y a plus d'un fichier .cpp non principal).

Répondre

10

Le compilateur ne se soucie pas - il compile chaque fichier .cpp dans obj fichier, et les fichiers .obj contiennent chacun une liste de symboles manquants. Donc dans ce cas, main.obj dit "il me manque point::point".

Il est alors l'emploi du éditeur de liens à prendre tous les fichiers OBJ, les combiner ensemble dans un fichier exécutable, et assurez-vous que chaque symboles manquants du fichier .obj sont disponibles dans l'un des autres fichiers OBJ - d'où le terme "éditeur de liens".

+0

Il ya généralement des fichiers .o, pas de .obj (mais cela n'a pas vraiment d'importance). – Zifre

+9

Ils ne sont "généralement" rien. GCC génère des fichiers .o par défaut, Visual Studio génère .obj. Aucun n'est plus "habituel" que l'autre. – jalf

0

Habituellement, vous les compiles séparément vous (ou avec un outil de construction comme make). Le fichier d'en-tête vous permet de les compiler dans n'importe quel ordre. Si vous les compilez ensemble, l'ordre est probablement l'ordre que vous passez à la commande du compilateur, mais cela n'a pas vraiment d'importance, ils sont tous finalement liés dans un exécutable.

1

L'ordre de compilation n'a pas d'importance. Tout est compilé par le compilateur, qui utilise les fichiers .h pour s'assurer que les symboles que vous utilisez sont au moins déclarés. C'est le travail de l'éditeur de liens, qui s'exécute après la fin du compilateur, de faire correspondre vos appels de méthode à leurs implémentations.

4

Si vous les incluez dans deux fichiers cpp différents, cela ne pose aucun problème. Si vous incluez deux fois le même en-tête, vous obtenez des erreurs pour les définitions dupliquées.

Vous devez utiliser des protections pour contourner cela.

En plus de votre dossier, avant tout code:

#ifndef HEADER_H_ //every header gets it's own name 
#define HEADER_H_ 

Sur le fond:

#endif 
+1

Je vote pour ce b/c c'est un modèle important qui contribue à cette discussion et ajoute beaucoup de valeur IMO. – jdt141

+1

Non: le PO pose des questions sur la séquence dans laquelle plusieurs fichiers CPP sont compilés (la réponse correcte étant que la séquence dans laquelle ils sont compilés n'a pas d'importance, puisqu'ils sont compilés indépendamment); le PO ne pose pas de questions sur la séquence dans laquelle les fichiers d'en-tête sont inclus dans chaque fichier CPP. – ChrisW

-1

C'est pourquoi vous voyez HEADER_H #ifndef et #define HEADER_H en haut de certains fichiers d'en-tête. La notion d'une seule inclusion de chaque fichier d'en-tête comme described here par exemple.

1

Le compilateur n'a pas besoin de savoir ce que pour compiler cpp fichiers.

L'éditeur de liens trie tous les .o compilé séparément (build à partir Cpp) fichiers sur et résout tout en un seul exécutable.

0

Ceci est un exemple d'application de théorie des graphes. Les modules compilés contiennent des décalages relatifs pour tous les blocs de code et jusqu'à l'éditeur de liens pour repérer les dépendances (graphique) pendant la construction du fichier exécutable.

Questions connexes