2010-11-09 24 views
3

J'ai une classe C++ que j'utilise, et il y a une fonction qui n'apparaît pas quand je regarde le fichier .o avec `nm --demangle ', et la fonction est manquante quand le programme essaie de s'exécuter , même si tout va bien.Pourquoi une fonction n'est pas définie dans le fichier .o pour cette classe C++?

L'en-tête ressemble à:

#ifndef __COLLECTION_H 
#define __COLLECTION_H 

#include <vector> 

#include "ObjectInstance.h" 

using namespace std; 

template <class T> 
class Collection : public ObjectInstance 
{  
protected: 
    vector<T*> items; 
    void internalInsertAt(T* item, int index); 
    void internalRemoveIndex(int index); 
    void internalRemoveItem(T* item); 

public: 
    virtual ~Collection(); 
    // Specific functions for this interface 
    static int item(jsplugin_obj *this_obj, jsplugin_obj *function_obj, int argc, 
    T* internalGetItem(int index); 
    int getSize(); 
    void addItem(T* item); 
}; 

#endif 

et la fonction addItem est implémenté comme

template <class T> 
void Collection<T>::addItem(T* item) 
{ 
    items.push_back(item); 
} 

L'erreur que je reçois est de lorsque je tente d'hériter de cette classe dans un autre et présente à runtime: undefined symbol: _ZN10CollectionIN4NJSE5TrackEE7addItemEPS1_

Je sens qu'il me manque quelque chose de simple ici, mais je ne peux pas dire de quoi il s'agit.

+0

Avez-vous spécifié la bibliothèque lors de la liaison? – t0mm13b

Répondre

2

Le compilateur a besoin d'avoir accès à toute la définition du modèle (pas seulement la signature) de addItem afin de générer du code pour chaque instanciation du modèle, de sorte que vous devez déplacer sa définition à votre tête i.e. suivre la inclusion model.

Les compilateurs C++ modernes d'Infact ne prennent pas facilement en charge le modèle de compilation séparé pour les modèles.

+2

Great link. La section 6.1.1, intitulée "Erreurs du lieur", passe en revue le problème exact dont se plaint le PO. –

+0

La référence de newbie canonique est C++ FAQ item [35.12 Pourquoi est-ce que je ne peux pas séparer la définition de ma classe templates de sa déclaration et la mettre dans un fichier .cpp?] (Http://www.parashift.com/c++-faq -lite/templates.html # faq-35.12), + les éléments suivants. –

+0

@Alf: Hmm c'est vrai. J'aurais dû donner ce lien aussi en plus de [C++ Templates '] (http://books.google.com/books?id=EotSAwuBkJoC&pg=PA61&lpg=PA61&dq=Inclusion+model+in+templates&source=bl&ots=iwO-H5_f8b&sig= _lQy9I36pfxWuU5iIw1IDCw-uK0 & hl = fr & ei = guCOTMbqGJHyvQPzs9DUCw & sa = X & oi = livre_résultat & ct = résultat & resnum = 3 & ved = 0CBwQ6AEwAg # v = onepage & q = Inclusion% 20modèle% 20in% 20templates & f = faux) lien. –

3

La fonction est-elle dans un fichier d'en-tête ou un fichier source? La façon la plus simple de traiter les modèles est de mettre toutes les définitions de modèles dans les fichiers d'en-tête, pour garantir que la définition est disponible pour tout code l'instanciant.

3

Eh bien, je pense que c'est parce que la fonction est membre d'un modèle. En C++, vous ne pouvez pas compiler des modèles (du moins pas facilement). Si vous souhaitez distribuer des classes de modèles, écrivez tout le code dans l'en-tête.

2

Les modèles dans des unités de compilation séparées peuvent être un cauchemar et nécessitent un sérieux travail de compilation. N'oubliez pas que des versions spécifiques de votre fonction de modèle doivent être compilées pour chaque type T pour lequel vous essayez d'instancier le modèle. Pour cette raison, le plus simple est de placer toutes vos définitions de fonctions de modèle dans le fichier d'en-tête '.h'.