IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Autres éditeurs Discussion :

[débutant] doit utiliser g++ -fpermissive


Sujet :

Autres éditeurs

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 42
    Par défaut [résolu] [débutant] doit utiliser g++ -fpermissive
    bonjour bonjour !

    alors voilà, je prends la suite d'un petit projet développé en c++, langage dont j'ai pas l'habitude (je suis plutôt java).
    un fichier pose problème : il génère des erreurs qui me forcent à utiliser g++ -fpermessive pour en faire des warnings.
    de plus, ce fichier implémente une liste chaînée et j'ai besoin d'utiliser son opérateur [], lequel déconne.
    quelqu'un pourrait-il m'aider à corriger ce fichufichier ?

    voici le fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    /**
    * List.h
    */
     
    #include <vector>
    using namespace std;
     
     
    template<class T>
    class List :
    	private vector<T>
    {
    public:
    	List(void){};
    	~List(void){};
     
    	int length(){return (int)size();}
    	bool isEmpty(){return empty();}
    	void add(T element){push_back(element);}
    	T pop()
          {int r=last(); pop_back();return r;} 
    	T operator[](int rank){return at(rank);}
    	int last(){return at(size()-1);}
    	int first(){return at(0);}
    	void clear(){vector<T>::clear();}
    	void append(List<T> liste)
          {for(int i=0;i<(int)liste.size();i++)add(liste[i]);}
    	void replace(T element,int offset );
    	void erase(int offset){vector<T>::erase(begin()+offset);}
    };
     
    template <class T> inline void List<T>::replace(T element,int offset )
    {
        insert(begin()+offset,element);
        erase(offset+1);
    }
    voilà les warnings qui apparaissent quand je compile un .cpp utilisant ce fichier List.h en utilisant "g++ -fpermissive" :

    List.h: In member function `int List<T>::length()':
    List.h:39: warning: there are no arguments to `size' that depend on a template parameter, so a declaration of `size' must be available
    List.h: In member function `bool List<T>::isEmpty()':
    List.h:40: warning: there are no arguments to `empty' that depend on a template parameter, so a declaration of `empty' must be available
    List.h: In member function `T List<T>::pop()':
    List.h:43: warning: there are no arguments to `pop_back' that depend on a template parameter, so a declaration of `pop_back' must be available
    List.h: In member function `T List<T>::operator[](int)':
    List.h:47: warning: there are no arguments to `at' that depend on a template parameter, so a declaration of `at' must be available
    List.h: In member function `int List<T>::last()':
    List.h:48: warning: there are no arguments to `size' that depend on a template parameter, so a declaration of `size' must be available
    List.h: In member function `int List<T>::first()':
    List.h:49: warning: there are no arguments to `at' that depend on a template parameter, so a declaration of `at' must be available
    List.h: In member function `void List<T>::erase(int)':
    List.h:54: warning: there are no arguments to `begin' that depend on a template parameter, so a declaration of `begin' must be available
    List.h: In member function `void List<T>::replace(T, int)':
    List.h:61: warning: there are no arguments to `begin' that depend on a template parameter, so a declaration of `begin' must be available
    quand je compile sans "-fpermissive", j'ai simplement des "error" à la place des "warning", et un message disant que je peux à la limite utiliser -fpermissive".

    pour info, ce projet utilise l'environnement de compilation mingw32.

    voilà, j'espère avoir été suffisamment clair.... si quelqu'un pouvait m'aider çà me rendrait vraiment un grand service :-).
    merci !

  2. #2
    Membre chevronné
    Profil pro
    Enseignant
    Inscrit en
    Avril 2004
    Messages
    440
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2004
    Messages : 440
    Par défaut
    Salut !!

    Tes fonctions "size", "empty", "pop_back", "at", "begin" ne sont pas implémentées...
    C'est donc normal que le compilo te rale dessus : tu dois les implémenter dans ta classe List...

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int length(){return (int)size();}
    La fonction size() telle que tu l'appelles doit logiquement être une méthode de la classe List. Or aucune déclaration de cette méthode n'est faite, ni aucune implémentation...


    Moi je verrais plus un truc comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    /**
    * List.h
    */
     
    #include <vector>
    using namespace std;
     
     
    template<class T>
    class List 
    {
     
    private :
      vector<T> TVector;
     
    public:
     
       List(void){};
       ~List(void){};
     
       int length(){return (int)TVector.size();}
       bool isEmpty(){return TVector.empty();}
       void add(T element){TVector.push_back(element);}
       T pop()
          {int r=TVector.last(); TVector.pop_back();return r;}
       T operator[](int rank){return TVector.at(rank);}
       int last(){return TVector.at(size()-1);}
       int first(){return TVector.at(0);}
     
       etc...
    };
    En fait ça doit être un problème de namespace, à cause du "List:private vector<T>"...
    C'est vraiment pas une notation facilement lisible !!

    A+

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 42
    Par défaut
    oui j'ai remarqué çà aussi ; j'ai pensé que ces méthodes étaient implémentées dans la classe vector. comme je l'ai écrit je récupère un projet déjà développé alors j'ai du mal (déjà que le c++ bien codé j'ai du mal... ).
    je vais aller chercher de la doc sur la classe vector pour trouver les bons appels de méthode.

    merci pour ta réponse!

  4. #4
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Par défaut
    Je ne crois pas que heriter de vector soit une bonne idée à la base.

    mieux vaux d'agreger comme le sugere mathieu_t.

    ensuite il faut sans doute que tu prefixes les appels par vector<T>:: pour qu'il ait le parametre Template pour instancier la fonction.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 42
    Par défaut
    eh je suis avecugle moi ... j'ai lu le message de mathieu_t que jusqu'au premier cadre "code". je vais essayer cette correction tout de suite.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 42
    Par défaut
    eh ben voilà, çà marche ! meeeerciiii beaucouuuuuuuup !

  7. #7
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Citation Envoyé par Gandalf
    Je ne crois pas que heriter de vector soit une bonne idée à la base.
    L'héritage privé ne permet pas de substitution -- plus besoin de faire attention au LSP.
    Par contre, pour réexporter les fonctions de la classe qui sert à se définir, il faut les réinjecter avec using.
    Pour l'utilisation depuis le corps des fonctions de la classe fille, le standard exige de préfixer l'appel par this-> ou par le nom complet (avec paramètres) de la classe parente.

    (Après, il y aurait des trucs à dire sur des choix, plus que moyens, du code)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 42
    Par défaut
    Sacré message que voilà pour le mauvais en c++ que je suis. Je ne comprends que ta 3ème phrase .

    pourrais-tu me donner quelques liens qui me permettraient de comprendre (ou même pourrais-tu m'expliquer ? ;-) ) ce qu'est la substitution, le LSP (apparemment c'est Liskov Substitution Principle mais çà me parle pas bcp +), et "réinjecter une fonction avec using" ?

    pour ce qui est de ta parenthèse, pourrais-tu critiquer les choix qui ont été faits ? çà m'intéresserait beaucoup.

  9. #9
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    En schématisant un max, on a deux type d'héritages
    - un pour réutiliser du code -- que quantité de bouquins vendaient sans en comprendre les ramifications (-> rupture vraissemblable du LSP)
    - un pour "être utilisable en place de", ce qui rejoint la notion "est-un" et le LSP (qui est bien le principe de substitution de liskov). En gros, un objet d'une classe fille est utilisable là où l'on attend un objet d'une classe mère. Avec tous les invariants qui sont attendus, selon le point de vu considéré, qui devront être respectés. Typiquement mis en oeuvre avec de l'héritage public.

    Avec l'héritage public, on peut très bien juste réutiliser du code, mais ce n'est pas toujours très bien venu dans la mesure où la syntaxe nous permet de substituer tandis qu'au niveau comportement les invariants seront brisés.

    Le gros exemple scolaire est celui qui dit qu'un carré n'est en aucun cas un rectangle.

    Qui parle mieux, AMHA, on a les listes. P.ex. un classe liste va disposer de la fonction insérer-a-une-certaine-position. La classe liste triée : la fonction insérer qui va insérer au bon endroit pour respecter l'ordre.
    Supposons que ListeTriée dérive publiquement de Liste (ce que je dis est aussi valable pour les autres langages OO dont le Java). Alors, la classe ListeTriée va aussi disposer de la fonction insererA().
    Si à un moment donné, "lt" une ListeTriée vérifie l'invariant "qq soient i<j, lt[i]<=lt[j]". L'emploi de insererA() peut briser l'invariant. Redéfinir la fonction pour lever une exception n'est pas non plus une bonne idée car, une fonction qui utilise des listes va se retrouver à planter si on lui donne la mauvaise liste -- alors que ce genre de vérification peut et doit être réalisée à la compilation.

    Bref, dans tous les langages, on peut faire abstraction du détail d'implémentation en encapsulant le code qui sert à l'implémentation dans un objet que l'on aggrège. En C++, on dispose également des héritages privés et protégés -- qui impliquent au passage un couplage bien plus fort.

    Si l'héritage privé avait été utilisé dans le code que tu reprends, c'est certainement pour cette raison : le but est de réutiliser du code et non d'être utilisé en place d'une liste standard.


    Par "réinjecter avec using", j'entends :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct M {
        void f();
    };
     
    struct F : private M {
        void g();
        using M::f;
    };
    ...
    F fille;
    fille.f(); // sans le using, le compilo gueulerait en l'état.

    Pour le code,
    - il manque profusion de "const" là où ils ont du sens.
    - l'utilisation d'un sale cast à la C pour revenir à "int" en place de size_type qui était parfaitement acceptable
    - pop() n'est pas exception-safe et sa signature ne lui permet pas de l'être. Au choix, il faut garder la séquence back() + pop() des queues, ou alors extraire via paramètre en référence sortante ->
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void pop(T & out) { out = this->back(); this->pop_back(); }
    (Pose toi la question de ce qu'il se passe si il y a une exception au moment de l'une des deux copies de l'élément à extaire)
    - replace pouvait simplement s'écrire avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void replace (size_type offset, T const& v) 
    { this->operator[](offset) = v;}
    - Les paramètres sont tous copiés au lieu d'êtrte pris par référence constante.
    - pour append, std::copy + std::back_inserter faisent l'affaire et auraient été plus efficaces -- selon l'idiome classique pour concaténer des containers standard.

    Bref. Je ne suis pas sûr que cette réinvention de std::queue se justifie pleinement.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 42
    Par défaut
    je te remercie pour toutes ces réponses. pour le moment jai lu assez rapidement, je pense avoir à peu près compris mais je relirai plus à fond plus tard.
    bye bye ! :-)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant(e)]utilisation de jxl
    Par yham dans le forum Documents
    Réponses: 5
    Dernier message: 04/07/2005, 14h01
  2. [...] doit utiliser une requête qui peut être mise à jour
    Par requiemforadream dans le forum ASP
    Réponses: 4
    Dernier message: 26/04/2005, 09h12
  3. [Débutant(e)] utiliser jsk 1.4.2 et eclipse 2.1.3
    Par iadelajoie dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 20/01/2005, 11h38
  4. [Débutant] Aide utilisation fonctions :(
    Par trakiss dans le forum Débuter
    Réponses: 10
    Dernier message: 27/08/2004, 15h59
  5. LEFT JOIN avec Oracle 8i ne va pas... doit utiliser (+)
    Par loikiloik dans le forum Langage SQL
    Réponses: 10
    Dernier message: 21/04/2004, 16h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo