mercredi 25 juillet 2018

Undefined symbols for architecture x86_64 (Templates)

Hello I have a problem compiling my C++ project and I can't figure out the error message. I have already looked at the questions in this forum that are based on the same problem but none of them seem to have the same origin.

Before you start reading this post.

  • Limit your search to the header files(Definition of the methods)
  • And the declarations of the methods in the .cpp files

I suspect that the error occurs there.

Macbook pro 13", project compiled on CLion 2016.3.2 EAP

MAKEFILE

cmake_minimum_required(VERSION 3.6)
project(C__Programm6)

set(CMAKE_CXX_STANDARD 11)

set(SOURCE_FILES main.cpp BaseException.cpp BaseException.h Couleur.cpp Couleur.h Forme.cpp Forme.h InvalidColorException.cpp InvalidColorException.h Ligne.cpp Ligne.h Pixel.cpp Pixel.h Point.cpp Point.h Rectangle.cpp Rectangle.h ListeBase.cpp ListeBase.h Liste.cpp Liste.h)
add_executable(C__Programm6 ${SOURCE_FILES})

The Error message I get:

Scanning dependencies of target C__Programm6
Undefined symbols for architecture x86_64:
  "Liste<int>::Liste(Liste<int> const&)", referenced from:
      Essai1() in main.cpp.o
  "Liste<int>::Liste()", referenced from:
      Essai1() in main.cpp.o
  "ListeBase<int>::getNombreElements()", referenced from:
      Essai1() in main.cpp.o
  "ListeBase<int>::Affiche()", referenced from:
      Essai1() in main.cpp.o
  "ListeBase<int>::estVide()", referenced from:
      Essai1() in main.cpp.o
  "ListeBase<int>::~ListeBase()", referenced from:
      Liste<int>::~Liste() in Liste.cpp.o
  "ListeBase<int>::operator=(ListeBase<int> const&)", referenced from:
      Liste<int>::operator=(Liste<int> const&) in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [C__Programm6] Error 1
make[2]: *** [CMakeFiles/C__Programm6.dir/all] Error 2
make[1]: *** [CMakeFiles/C__Programm6.dir/rule] Error 2
make: *** [C__Programm6] Error 2

Main.cpp:

#include <stdlib.h>
#include <iostream>
#include <time.h>

#include "Liste.h"
//#include "ListeTriee.h"
//#include "Iterateur.h"

#include "Couleur.h"

using namespace std;

int  Menu();
void Essai1();
/*void Essai2();
void Essai3();
void Essai4();
void Essai5();
void Essai6();
void Essai7();
void Essai8();*/

int main(int argc,char* argv[])
{

... ("..." represents he part where it prints the menu of the application, where you can chose between Essai 1 - 8)

void Essai1() {
    cout << "----- 1. Test du template Liste avec des entiers --------------------------------------------" << endl;
    cout << "----- 1.1 Creation et gestion d'une Liste ---------------------------------------------------" << endl;

    Liste<int> liste;
    liste.Affiche();                                       // --> ()
    cout << endl;

    cout << "Liste Vide ? " << liste.estVide() << endl;
    cout << "On insere 3,-2,5,-1 et 0..." << endl;
    liste.insere(3);
    liste.Affiche();

    liste.insere(-2);
    int *pI = liste.insere(5);
    liste.insere(-1);
    liste.insere(0);
    cout << "Liste Vide ? " << liste.estVide() << endl;
    liste.Affiche();                                       // --> (3 -2 5 -1 0)
    cout << "La liste contient " << liste.getNombreElements() << " elements." << endl;
    cout << "On modifie le 3eme element :" << endl;
    *pI = 100;
    liste.Affiche();

    cout << "----- 1.2 Test du constructeur de copie -----------------------------------------------------" << endl;
    {
        Liste<int> liste2(liste);
        cout << "----> Voici la copie :" << endl;
        liste2.Affiche();
        cout << "----> On insere 50 dans la copie :" << endl;
        liste2.insere(50);
        liste2.Affiche();
        cout << "----> Destruction de la copie..." << endl;
    }
    cout << endl << "Et revoici la liste de depart : " << endl;
    liste.Affiche();
    cout << endl;

    cout << "----- 1.3 Test de l'operateur = -------------------------------------------------------------" << endl;
    {
        Liste<int> liste3;
        liste3 = liste;
        cout << "----> Voici le resultat de l'operateur = :" << endl;
        liste3.Affiche();
        cout << "----> On insere 50 dans la nouvelle liste :" << endl;
        liste3.insere(50);
        liste3.Affiche();
        cout << "----> Destruction de la nouvelle liste..." << endl;
    }
    cout << endl << "Et revoici la liste de depart : " << endl;
    liste.Affiche();
    cout << endl;
}

ListeBase.h:

#ifndef C_PROGRAMM6_LISTEBASE_H
#define C_PROGRAMM6_LISTEBASE_H

#include <iostream>
#include <stdlib.h>
using namespace std;

template<class T> struct Cellule{
    T valeur;
    Cellule<T> *suivant;
};

template<class T> class ListeBase{

protected:
    Cellule<T> *ptete;
    Cellule<T> *CopyList(const ListeBase<T> &);
    void VideListe();
public:
    //Constructeurs
    ListeBase();
    ListeBase(const ListeBase<T> &);
    //Destructeur
    virtual ~ListeBase();
    //Autre
    bool estVide();
    int getNombreElements();
    void Affiche();
    //operateurs surcharge
    ListeBase<T> &operator=(const ListeBase<T> &);
    //Methodes virtuelles
    virtual T *insere(const T &) = 0;

};
template class Cellule<int>;
#endif //C_PROGRAMM6_LISTEBASE_H

ListeBase.cpp

#include "ListeBase.h"
template <class T>
ListeBase<T>::ListeBase() {
    cout << "-> Constructeur par defaut [ListeBase]" << endl;

     ptete = NULL;
}
template <class T>
ListeBase<T>::ListeBase(const ListeBase<T> &new_Cellule) {
    cout << "-> Constructeur d'initialisation [ListeBase]" << endl;

    CopyList(new_Cellule);
}
template <class T>
ListeBase<T>::~ListeBase() {
    cout << "-> Destructeur [ListeBase]" << endl;

    VideListe();
}
template <class T>
bool ListeBase<T>::estVide()  {
    if(!ptete)
        return true;
    else
        return false;
}
template <class T>
void ListeBase<T>::Affiche() {
    Cellule<T> *temp;
    temp = ptete;

    if(temp != NULL) {
        while (temp != NULL) {
            cout << temp->valeur << " ";
            temp->suivant;
        }
    }
    else
        cout << "La liste est vide" << endl;
}
template <class T>
int ListeBase<T>::getNombreElements()  {
    int nombElements = 0;
    Cellule<T> *temp;
    temp = ptete;

    while(temp -> suivant != NULL)
    {
        nombElements++;
        temp -> suivant;
    }

    return nombElements;
}
template <class T>
ListeBase<T>& ListeBase<T>::operator=(const ListeBase<T> &new_ListeBase) {
    VideListe();
    CopyList(new_ListeBase);

    return *this;
}
template <class T>
Cellule<T>* ListeBase<T>::CopyList(const ListeBase<T>& lb)
{
    Cellule<T> *pTmp, *tete, *pTrav, *pNext;

    if(lb.ptete == NULL)
        return NULL;

    /*      Copie de tete       */
    tete = new Cellule<T>;

    tete->valeur = lb.ptete->valeur;
    tete->suivant = NULL;

    /*      Copie de la liste   */
    pTmp = lb.ptete->suivant;
    pNext = tete;
    while(pTmp != NULL)
    {
        pTrav = new Cellule<T>;

        /*      Nouvelle liste  */
        pTrav->valeur = pTmp->valeur;
        pNext->suivant = pTrav;
        pNext = pTrav;

        /*      Ancienne liste  */
        pTmp = pTmp->suivant;
        pTrav->suivant = NULL;
    }
    return tete;
}
template <class T>
void ListeBase<T>::VideListe()
{
    Cellule<T> *pTmp, *pDel;

    if(ptete != NULL)
    {
        pTmp = ptete;
        while(pTmp != NULL)
        {
            pDel = pTmp;
            pTmp = pTmp->suivant;
            delete pDel;
        }
    }
    ptete = NULL;
}

Liste.h

#ifndef C_PROGRAMM6_LISTE_H
#define C_PROGRAMM6_LISTE_H

#include "ListeBase.h"

template <class T> class Liste : public ListeBase<T>{
public:
    //Constructeurs
    Liste();
    Liste(const Liste<T> &);
    //Destructeur
    virtual ~Liste();
    //Methodes virtuelles
    virtual T *insere(const T &);
};
template class Liste<int>;
#endif //C_PROGRAMM6_LISTE_H

Liste.cpp

#include "Liste.h"

template <class T>
Liste<T>::Liste() : ListeBase<T>(){
    cout << "-> Constructeur par defaut [Liste]" << endl;
}
template <class T>
Liste<T>::Liste(const Liste<T> &new_Liste) : ListeBase<T>(new_Liste) {
    cout << "-> Constructeur de copie [Liste]" << endl;
}

template <class T>
Liste<T>::~Liste() {
    cout << "-> Destructeur [Liste]" << endl;
}
template <class T>
T* Liste<T>::insere(const T &new_T) {
    Cellule <T> *ptemp, *val;
    ptemp = new Cellule<T>;
    ptemp -> suivant = NULL;
    ptemp -> valeur = new_T;

    val = this -> ptete;

    if(this -> ptete == NULL){
        val -> suivant = ptemp;
    }

    return &ptemp -> valeur;
}

Aucun commentaire:

Enregistrer un commentaire