Vecteur de pointeurs fonction de compensation de modèle ne peut pas compiler avec le message « de référence non définie »

StackOverflow https://stackoverflow.com/questions/914460

  •  06-09-2019
  •  | 
  •  

Question

J'ai fait pour un programme de mes une petite fonction pour effacer les différents std :: vecteurs de pointeurs que j'ai.

template <class S>
void clearPtrVector(std::vector<S*> &a,int size)
{
    for(size_t i = 0; i < size; i++)
         delete a[i];

    a.clear();
}

Je dois avoir fait quelque chose de mal ici, bien que depuis lors de l'appel de cette fonction dans un destructor comme ceci:

clearPtrVector(neurons,neurons.size());

Je reçois deux fois la référence définie suivant:

undefined reference to `void clearPtrVector<Neuron>(std::vector<Neuron*,std::allocator<Neuron*> >&, int)'

Je dois admettre que je ne suis pas familier avec ce que le std :: allocateur est, donc je ne peux pas deviner ce que le problème pourrait être ici. Toute aide est vraiment appréciée. Merci d'avance!

-Lefteris

Était-ce utile?

La solution

Hot Fix

Ecrire suivant à la place:

  template <class Vector>
  void clearPtrVector(Vector &a)
  {
    for(size_t i = 0; i < a.size(); i++)
         delete a[i];

    a.clear();
  }

Assurez-vous de définir le modèle quelque part où le compilateur peut le voir avant chaque utilisation du modèle. Si vous ne créez pas une déclaration, vous devriez être en sécurité, sinon vous devriez obtenir une erreur de compilation. Si vous créez une déclaration pour une raison quelconque, être le double d'inclure la définition carefull partout au besoin.

Remaniement

Cela dit, je pense que la bonne solution serait de repenser votre conception et d'utiliser un récipient qui se chargera de la destruction correctement, de sorte que vous ne devez pas le faire manuellement, ce qui est pénible, et presque impossible de le faire correctement si vous avez besoin de sécurité d'exception. Utilisez std::shared_ptr au lieu des pointeurs premières ou std::auto_ptr avec un récipient qui est capable de les tenir (std::vector ne peut pas stocker les valeurs auto_ptr). Une solution possible serait d'utiliser Boost pointeur Container

Autres conseils

Votre mise en œuvre de clearPtrVector dans un fichier d'en-tête? Parce que s'il est dans un fichier séparé Cpp, l'éditeur de liens ne le trouve pas.

Quelques choses:

Dans votre code d'origine, ne passe pas dans la taille; juste l'obtenir à partir du vecteur:

template <class S>
void clearPtrVector(std::vector<S*> &a)
{
    for(size_t i = 0; i < a.size(); ++i)
    {
         delete a[i];
    }

    a.clear();
}

En second lieu, il suffit de passer dans le vecteur lui-même, pas le type il pointe:

template <class Vector>
void clearPtrVector(Vector &vec)
{
    for(size_t i = 0; i < vec.size(); ++i)
    {
         delete vec[i];
    }

    vec.clear();
}

En troisième lieu, cette erreur semble que vous l'avez placé dans un fichier .cpp. Le code sera généré lorsque vous appelez la fonction, ce qui signifie que le compilateur a besoin de connaître la définition de la fonction. Déplacer la fonction dans le fichier d'en-tête, de sorte que le compilateur peut la trouver.

Enfin, envisagez d'utiliser des choses plus adaptées à ceci:

Assurez-vous de cette fonction dans un fichier d'en-tête (.h, * .hpp) parce que si vous l'avez défini dans un fichier source avec un prototype dans un fichier d'en-tête vous avez une erreur d'éditeur de liens de référence non définie.

erreur de référence non définie signifie que le compilateur a trouvé la référence de la fonction, mais linker n'a pas trouvé une référence de cette fonction parmi les fichiers objets. Toute fonction de modèle doit être défini dans un fichier d'en-tête de sorte que le compilateur sera en mesure de le mettre dans un fichier source qui utilise la fonction.

est-ce pas la refonte d'un double de nettoyage-up-un-stl-list vecteur-de-pointeurs

Remarque

Si vous n'utilisez pas l'un des pointeurs intelligents, utilisez

Comme je l'ai fourni dans ma réponse à votre première question https://stackoverflow.com/questions/891913?sort=newest , une réponse est la suivante:

template <class C> void FreeClear( C & cntr ) {
    for ( typename C::iterator it = cntr.begin(); 
              it != cntr.end(); ++it ) {
        delete * it;
    }
    cntr.clear();
}

qui fonctionne pour tous les types de conteneurs. Notez que le paramètre de taille n'est pas fourni, mais est obrtained de la collection -. C'est la bonne façon de concevoir ces fonctions, fournir la taille en tant que valeur séparée ne peut conduire à la catastrophe

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top