Classe contenant vecteur template [Résolu]

Signaler
Messages postés
22
Date d'inscription
lundi 23 juin 2003
Statut
Membre
Dernière intervention
9 juin 2007
-
Messages postés
22
Date d'inscription
lundi 23 juin 2003
Statut
Membre
Dernière intervention
9 juin 2007
-
Bonjour,
Je suis sur un programme cpp sous linux. J'ai créé une classe template "Vecteur" qui est censée pouvoir recevoir plusieurs types dont des classes que j'ai créé dans mon application.

Vecteur.h :

#ifndef  _VECTEUR_H_
#define  _VECTEUR_H_
#include
#include "PieceMusee.h"
#include "Personne.h"

using namespace std;

template <class X> class Vecteur
{   
    private:
        int nE;
        static int ind;
        int IndiceOK(const int i);
    public:
        X *Data;
        Vecteur() { cout << "->> Construction du vecteur" << endl; nE=0; }
        Vecteur(int n=10);
        ~Vecteur();
       
        inline int  getnE()       { return nE; }        inline void setnE(int n)  { nE n; Data new X[n]; }
       
        void Saisie();
        void Aff();
       
        void Add(X, int);
        X& operator[] (int i)    { if(IndiceOK(i)) return *(Data+i); }
};
#endif

Vecteur.cxx
#include "Vecteur.h"   

                               
                               
/*********************************************
* Vecteur template : Constructeur            *
*********************************************/
template <class X> Vecteur<X>::Vecteur(int n)
{
    if(n>=0)
    {
        #ifdef DEBUG
            cout << "Construction du vecteur";
        #endif
        Data=new X[n];
        nE=n;
    }
}

/*********************************************
* Vecteur template : Déstructeur             *
*********************************************/
template <class X>Vecteur<X>::~Vecteur()
{
    #ifdef DEBUG
        cout << "Destruction du vecteur";
    #endif
    if(Data)
        delete []Data;
}

/****************************************************************************
* Vecteur template : Méthode permettant de vérifier si l'indice est correct *
****************************************************************************/
template <class X>int Vecteur<X>::IndiceOK(const int i)
{
    if(i<0 || i>=nE)
    {
        cout << "<<<Erreur : Indice d'element inexistant!>>>";
        return 0;
    }
    return 1;
}

/*********************************************
* Vecteur template : Méthode d'affichage     *
*********************************************/
template <class X>void Vecteur<X>::Aff()
{
    for(int i=0; i<nE; i++)
        cout << Data[i] << endl;
}

/*********************************************
* Vecteur template : Méthode de saisie       *
*********************************************/
template <class X>void Vecteur<X>::Saisie()
{
    for(int i=0; i<nE; i++)
    {
        cout <<  "Elem " << i+1 << " : " << endl; cin >> Data[i];
    }
}

template <class X>void Vecteur<X>::Add(X obj, int i)
{
    Data[i] = obj;
}

template class Vecteur;
template class Vecteur;
template class Vecteur;
template class Vecteur<MembrePersonnel>;

La classe semble bien fonctionner puisque dans le Main je suis capable de créer un vecteur d'entier, de le remplir et l'aficher et de faire de même avec un vecteur de PieceMuseeArt (classe de mon applic).

La ou le problème se pose, c'est
quand je veux q'une de mes classes possède un tel vecteur en variable membre,
j'arrive à le déclarer sans provoquer d'erreur à la compilation,
mais je n'arrive jamais à l'utiliser,
la j'ai des erreurs à la compilation du style "have no type".
Je pense que j'ai juste oublié une petite chose dans le code pour que le compilateur comprenne bien le type de la variable qui instanciera la classe template vecteur mais je 'y arrive pas,
si quelqu'un sait m'aider c'est cool, merci .

6 réponses

Messages postés
22
Date d'inscription
lundi 23 juin 2003
Statut
Membre
Dernière intervention
9 juin 2007

J'ai trouvé mon erreur et elle ne concernait pas directement les templates, j'lexplique quand même.

Dans la classe vecteur j'ai ces 2 constructeurs  :
Vecteur( ){...}                    // constructeur par defaut
Vecteur(int x = 0) {...}       // constructeur initialisqation avec valeur par défaut

Mon erreur venant du fait que je ne pouvais jamais appeler le constructeur par défaut vu l'ambiguité créée entre constructeur par défaut et constructeur avec une valeur par défaut...
Messages postés
22
Date d'inscription
lundi 23 juin 2003
Statut
Membre
Dernière intervention
9 juin 2007

Et donc pour l'exemple, ma classe Personnel déclar un Vecteur<MembrePersonnel>

Personnel
<hr size="2" width="100%" />#ifndef _PERSONNEL_H_
#define _PERSONNEL_H_

#include "Vecteur.h"
#include "Store.h"

class Personnel
{
    protected:
        int ne;
        Vecteur<MembrePersonnel> vmp(int);

    public:
        Personnel() { ne=0; };
        void lirePersonnel();
        void ecrirePersonnel();
        void modifPersonnel();
};
#endif
<hr size="2" width="100%" />C'est la seule maniere de déclarer que j'ai réussi à compiler je ne sais pas si elle est valable.
Mais ensuite je suis incapable d'utiliser ce vecteur,

Personnel.cxx
<hr size="2" width="100%" />#include "Personnel.h"

void Personnel::lirePersonnel()
{
    ifstream f("MembrePersonnel.txt");
    MembrePersonnel Lu;
    f >> ne;                                                   // récupere un nombre dans le fichier
    vmp.setnE(ne);
    int i=0;
    while(i<ne)
    {
        if(!strcmp(Lu.getTitre(), "psc"))
        {PersonnelScientifique p(Lu); vmp.Add((MembrePersonnel)Lu, i); }
        else
            if(!strcmp(Lu.getTitre(), "psu"))
            {PersonnelSurveillance(Lu);}
            else
                if(!strcmp(Lu.getTitre(), "pa"))
                {PersonnelAdministratif(Lu);}
        i++;
    }
}

void Personnel::ecrirePersonnel()
{

    if(ne>0)
    {
        ofstream ofstr("Personnel.txt");
        for(int i=0; i<ne; i++)
        {
            ofstr << vmp[i];
             
        }
    }
}

void Personnel::modifPersonnel()
{

}
<hr size="2" width="100%" />Voila dans ce code chaque ligne qui contient 'vmp' provoquera une erreur du type "...have no type...".
Merci de votre aide.
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
Ca sert a rien dans ton cas ca:

template class Vecteur;
template class Vecteur;
template class Vecteur;
template class Vecteur<MembrePersonnel>;

Par ailleurs, c'est pas bon ca:
Vecteur.h :

#ifndef  _VECTEUR_H_
#define  _VECTEUR_H_
#include
#include "PieceMusee.h"
#include "Personne.h"

Les deux derniers include n'ont rien a faire ici. c'est pas normal de les voir la. Mais tu en avais besoin avec tes "template class Vecteur" qui sert a rien donc tu peux dégarer ces includes qui devvait provoquer tes erreurs de compilation due à des includes en boucle.

Donc si ta une classe:

class
{
Vecteur m_intVecteur;
};

Doit pas y avoir de soucis.
Messages postés
22
Date d'inscription
lundi 23 juin 2003
Statut
Membre
Dernière intervention
9 juin 2007

Salut et merci pour ton aide.
- Les déclarations template dont tu me dis qu'elles ne servent à rien dans mon cas sont utiles pour une autre partie de l'application.


- Les include "... .h" je les ai mis par apres pour tester un peu désespérément. Cependant ils ne peuvent pas provoquer d'erreur de boucles puisque comme tu peux le voir dans le code ils sont protégés par des "ifdef".

- Je pense que le problème vient de cette ligne :
Vecteur<MembrePersonnel> vmp(int);


jai mis (int) parceque c'est tout ce que j'ai trouvé qui était accepté à la compilation. sinon j'ai essayé de passer une valeur (définie dans une constante par exemple) ou bien rien du tout ( ) mais ces 2 options provoquent une erreur de compilation...

Encore merci pour ton aide
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
Non, ces déclarations template ne peuvent pas etre utile (sauf cas particulier), car elle sont implicite toute facon. Suffit de que l'écrire pour que le compilo le fasse. Donc ces définitions sont pas utiles et les enlever permettent de dégager les includes du fichier Vecteur.h.

Rah, mais j'avais pas vu ...

class Personnel
{
    protected:
        int ne;
        Vecteur<MembrePersonnel> vmp(int);

On peut PAS !! initialiser de variable membre. Faut le faire dans le constructeur.

"- Les include "... .h" je les ai mis par apres pour tester un peu
désespérément. Cependant ils ne peuvent pas provoquer d'erreur de
boucles puisque comme tu peux le voir dans le code ils sont protégés
par des "ifdef"."
=> Si, le pb peut venir des includes en boucle. Tes macros protegent contre les multiinclusions, mais c'est pas pour ca qu'on peut utiliser les include n'importe comment. Dans ton cas, tes classes ne seront jamais déclarés. Regarde ce que fais le compilo mentalement et tu verras qu'il passe jamais sur tes classes:

Les macros pour prévenir les inclusions multiples sont implicites. Je les mets pas pour pas allonger le code.
Fichier 1:
#include "Fichier2.h"
class Test1
{
    Test2 obj;
};

Fichier 2:
#include "Fichier1.h"
class Test2
{
    Test1 obj;
};

Fichier 3:
#include <fichier1.h>
#include <fichier2.h>

Tu pourras jamais compiler le fichier 3 à cause d'include déclaré n'importe comment.
Messages postés
22
Date d'inscription
lundi 23 juin 2003
Statut
Membre
Dernière intervention
9 juin 2007

J'ai trouvé mon erreur et elle ne concernait pas directement les templates, j'lexplique quand même.

Dans la classe vecteur j'ai ces 2 constructeurs  :
Vecteur( ){...}                    // constructeur par defaut
Vecteur(int x = 0) {...}       // constructeur initialisqation avec valeur par défaut

Mon erreur venant du fait que je ne pouvais jamais appeler le constructeur par défaut vu l'ambiguité créée entre constructeur par défaut et constructeur avec une valeur par défaut...