7
votes

Modèles et compilation séparé

Je veux écrire un programme en C ++ avec une compilation séparée et j'ai écrit ceci:

main.cpp p> xxx pré>

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 :


8
votes

Les classes de modèle doivent avoir les définitions de la méthode à l'intérieur du fichier d'en-tête.

Déplacez le code que vous avez dans le fichier .cpp à l'intérieur de l'en-tête ou créez un fichier appelé .Impl ou .Imp . le code là-bas et l'inclure dans l'en-tête.

Le compilateur doit connaître les définitions de la méthode pour générer du code pour toutes les spécialisations.

Avant de demander, non, il n'y a aucun moyen de garder la mise en œuvre en dehors de l'en-tête.



6
votes

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";
}


0 commentaires

1
votes

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>;


0 commentaires