Classe Template - Probleme d'edition de lien

ano2345 Messages postés 18 Date d'inscription dimanche 9 novembre 2008 Statut Membre Dernière intervention 22 décembre 2008 - 22 déc. 2008 à 14:15
humpff Messages postés 1 Date d'inscription jeudi 25 décembre 2008 Statut Membre Dernière intervention 25 décembre 2008 - 25 déc. 2008 à 18:29
Bonjour a tous,



<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /??>
 





J’essaie de developer sous Dev-C++ 4.9.9.2 une classe template MyVector qui contient un element qui est un objet vector.













J’ai commence par developper cette classe en considerant uniquement des vector<float>, et tout a tres bien fonctionne (le code suit) :






 








Fichier MyVector.hpp






#ifndef MyVector_hpp


#define MyVector_hpp



 




#include <vector>


using namespace std;



 




class MyVector


{


private:



    vector<float> m_Vector;



           


public:



    MyVector() {}



    MyVector(vector<float>& Vect);



    virtual ~MyVector() {}



    int size() const { return m_Vector.size(); }



    float operator[](int i) const { return m_Vector[i]; }



    void push_back(float f) { m_Vector.push_back(f); }



    MyVector& operator=(const MyVector& MyVect);



    MyVector operator+(const MyVector& MyVect) const;



    MyVector operator*(const MyVector& MyVect) const;



    friend ostream& operator<<(ostream& os, const MyVector& MyVect);



};






 






#endif






 








Fichier MyVector.cpp






#ifndef MyVector_cpp


#define MyVector_cpp



 




#include "MyVector.hpp"


#include <vector>


#include


using namespace std;



 




MyVector::MyVector(vector<float>& Vect)


{



    int i;



    for (i = 0; i < Vect.size(); i++) m_Vector.push_back(Vect[i]);


}



 





 




MyVector& MyVector::operator=(const MyVector& MyVect)


{



    if (this == &MyVect) return *this;



    m_Vector.erase(m_Vector.begin(), m_Vector.end());



    int i;



    for (i = 0; i < MyVect.size(); i++) m_Vector.push_back(MyVect[i]);



    return *this;


}



 





   


MyVector MyVector::operator+(const MyVector& MyVect) const


{



    MyVector Sum;



    if (m_Vector.size() != MyVect.m_Vector.size())



    {



        cout << "MyVector::operator+() - sizes don't match: program terminating\n";



       
exit(EXIT_FAILURE);    






    }






    int i;





    for (i = 0; i < m_Vector.size(); i++) Sum.push_back(m_Vector[i] + MyVect.m_Vector[i]);



    return Sum;        


}



 





   


MyVector MyVector::operator*(const MyVector& MyVect) const


{



    MyVector Product;



    if (m_Vector.size() != MyVect.m_Vector.size())



    {



        cout << "MyVector::operator*() - sizes don't match: program terminating\n";



        exit(EXIT_FAILURE);    



    }



    int i;



    for (i = 0; i < m_Vector.size(); i++) Product.push_back(m_Vector[i] * MyVect.m_Vector[i]);



    return Product;        


}   



 





 




ostream& operator<<(ostream& os, const MyVector& MyVect)


{



    int i;



    for (i = 0; i < MyVect.size(); i++) cout << MyVect[i] << "\t";



   
return os;       





}






 






#endif






 








Fichier TestMyVector.cpp






#include "MyVector.hpp"


#include <vector>


#include


using namespace std;



 




int main()


{



    vector<float> V1;



    int i;



    for (i = 1; i < 7; i++) V1.push_back(i*i*i);



   



    MyVector MV1(V1);



    cout << "size(MV1) = " << MV1.size() << "\n";



   
cout << MV1 << "\n";






   








    return 0;       





}






 







 






Puis, j’ai ensuite decide de construire la meme classe,  mais plus generale, en utilisant les template :






 







Fichier MyVector.hpp





#ifndef MyVector_hpp


#define MyVector_hpp



 




#include <vector>


using namespace std;



 




template<class T>


class MyVector


{



private:






    vector<T> m_Vector;






           







public:






  
 MyVector() {}





    MyVector(vector<T>& Vect);



    virtual ~MyVector() {}



    int size() const { return m_Vector.size(); }



    float operator[](int i) const { return m_Vector[i]; }



    void push_back(T f) { m_Vector.push_back(f); }



    MyVector<T>& operator=(const MyVector<T>& MyVect);



    MyVector<T> operator+(const MyVector<T>& MyVect) const;



    MyVector<T> operator*(const MyVector<T>& MyVect) const;



    friend ostream& operator<<(ostream& os, const MyVector<T>& MyVect);


};



 




#endif



 






Fichier MyVector.cpp





#include "MyVector.hpp"


#include <vector>


#include


using namespace std;



 





 




template<class T>


MyVector<T>::MyVector(vector<T>& Vect)


{



    int i;



    for (i = 0; i < Vect.size(); i++) m_Vector.push_back(Vect[i]);


}



 





 




template<class T>


MyVector<T>& MyVector<T>::operator=(const MyVector<T>& MyVect)


{



    if (this == &MyVect) return *this;



    m_Vector.erase(m_Vector.begin(), m_Vector.end());



    int i;



    for (i = 0; i < MyVect.size(); i++) m_Vector.push_back(MyVect[i]);



    return *this;


}



 





 




template<class T>


MyVector<T> MyVector<T>::operator+(const MyVector<T>& MyVect) const


{



    MyVector<T> Sum;



    if (m_Vector.size() != MyVect.m_Vector.size())



    {



        cout << "MyVector::operator+() - sizes don't match: program terminating\n";



        exit(EXIT_FAILURE);    



    }



    int i;



    for (i = 0; i < m_Vector.size(); i++) Sum.push_back(m_Vector[i] + MyVect.m_Vector[i]);



    return Sum;        


}



 





   


template<class T>


MyVector<T> MyVector<T>::operator*(const MyVector<T>& MyVect) const


{



  
 MyVector<T> Product;



    if (m_Vector.size() != MyVect.m_Vector.size())



    {



        cout << "MyVector::operator*() - sizes don't match: program terminating\n";



        exit(EXIT_FAILURE);    



    }



    int i;



    for (i = 0; i < m_Vector.size(); i++) Product.push_back(m_Vector[i] * MyVect.m_Vector[i]);



    return Product;        


}   



 





 





 




template<class T>


ostream& operator<<(ostream& os, const MyVector<T>& MyVect)


{



    int i;



    for (i = 0; i < MyVect.size(); i++) cout << MyVect[i] << "\t";



    return os;       


}



 




#endif



 






Fichier TestMyVector.cpp





#include "MyVector.hpp"


#include <vector>


#include


using namespace std;



 




int main()


{



    vector<float> V1;



    int i;



    for (i = 1; i < 7; i++) V1.push_back(i*i*i);



   



    MyVector<float> MV1(V1);



    cout << "size(MV1) = " << MV1.size() << "\n";




    cout << MV1 << "\n";






    return 0;       





}






 







 






Cette fois, lorsque que j’essaie de compiler cette version template, j’obtiens des erreurs d’editions.





Je ne reussis a compiler que si :






-         

je remplace #include "MyVector.hpp" par #include "MyVector.cpp" dans le fichier TestMyVector.cpp






-         

j’elimine toute trace de la fonction operator<< des 3 fichiers.






 






Quelqu’un pourrait-il m’expliquer pourquoi je ne peux pas compiler comme avec la classe non template ? (je m'arrache les cheveux)






 






Merci par avance,





Ano

1 réponse

humpff Messages postés 1 Date d'inscription jeudi 25 décembre 2008 Statut Membre Dernière intervention 25 décembre 2008
25 déc. 2008 à 18:29
Le problème est que l'on ne peut pas écrire les définitions des fonctions dans un fichier source lorsque l'on utilise des templates.

2 solutions s'offrent à toi: soit tout définir dans ton header, soit créer un autre fichier (par exemple .txx) pour écrire toutes tes définitions et faire un appel à ce fichier à la fin de ton .h avec #include fichier.txx. Les 2 reviennent au même.
0
Rejoignez-nous