Je veux écrire un programme en C ++ avec une compilation séparée et j'ai écrit ceci:
main.cpp p> pile.h p> ccyDhLTv.o:main.cpp:(.text+0x16): undefin
ed reference to `Stack<int>::Stack()'
ccyDhLTv.o:main.cpp:(.text+0x32): undefin
ed reference to `Stack<int>::push(int const&)'
collect2: ld returned 1 exit status
3 Réponses :
Les classes de modèle doivent avoir les définitions de la méthode à l'intérieur du fichier d'en-tête. P>
Déplacez le code que vous avez dans le fichier Le compilateur doit connaître les définitions de la méthode pour générer du code pour toutes les spécialisations. p>
Avant de demander, non, il n'y a aucun moyen de garder la mise en œuvre en dehors de l'en-tête. P> .cpp code> à l'intérieur de l'en-tête ou créez un fichier appelé
.Impl code> ou
.Imp code>. le code là-bas et l'inclure dans l'en-tête. P>
Vous voulez donc dire que je ne peux pas utiliser la compilation séparée lorsque j'utilise des modèles?
@Jordanborisov Voir Parasht.com/c++-faq-lite/templates.htmllle a> - section 12.
@Jordanborisov Eh bien c'est comme ça. Et c'est le point de modèles. Si vous voulez les utiliser, c'est ainsi que vous devez le faire.
@Jordanborisov: Si vous connaissez les types qui vont être transmis à vos modèles, vous pouvez les instantiez explicitement avec Stack de classe
Et comment je peux compiler le fichier stack.impl)?
@Jordanborisov: vous l'incluez dans l'en-tête, et cela sera inclus dans les fichiers source qui utilisent cet en-tête et compilés dans le cadre d'eux.
Je dirais qu'il sera plus pragmatique de comprendre à quel point la compilation est séparée fonctionne pour des fichiers normaux (non tempérés), puis comprennent comment le compilateur g ++ le fait pour le modèle.
Tout d'abord dans les fichiers normaux, lorsque le fichier d'en-tête contenant uniquement les déclarations sont #inclus dans le fichier principal, le prétraiteur remplace les déclarations de l'en-tête et le met au fichier principal. Ensuite, une fois la phase de prétraitement terminée, le compilateur fait une par une compilation du code source pur c ++ contenu dans les fichiers .cpp et le traduit en fichier d'objet. À ce stade, le compilateur ne dérange pas les définitions manquantes (des fonctions / classes) et les fichiers d'objet peuvent faire référence à des symboles non définis. Le compilateur peut donc compiler le code source tant qu'il est bien formé. P>
Puis pendant la phase de liaison, le compilateur relie plusieurs fichiers ensemble et il est au cours de cette étape, le linker produira une erreur sur les définitions manquantes / dupliquées. Si la définition de la fonction est correctement présente dans l'autre fichier, le produit Linker se déroule et la fonction appelée à partir du fichier principal est liée avec succès à la définition et peut être utilisée. P>
Pour les modèles, les choses fonctionnent différemment. Il sera illustratif de considérer un exemple, donc je choisis un simple: p>
Considérez le fichier d'en-tête pour la classe de matrice de modèle: p>
array.h p>
#include "array.h" #include <iostream> int main() { Array<int> int_array; Array<double> double_array; std::cout << int_array.getLength() <<"\n"; std::cout << double_array.getLength() << "\n"; }
Il est absolument possible d'avoir des modèles et une compilation séparée, mais seulement si vous connaissez à l'avance pour quels types le modèle sera instancié.
fichier d'en-tête sep_head.h code>: p>: p>:
#include "sep_head.h"
template< typename T >
void sep<T>::f() {}
template class sep<int>;
template class sep<double>;
template class sep<char>;
duplicatural possible de Pourquoi Si la mise en œuvre et la déclaration d'une classe de modèles se trouvent dans le même fichier d'en-tête?