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

C++ Discussion :

Débutant : HERITAGE


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 8
    Points : 1
    Points
    1
    Par défaut Débutant : HERITAGE
    Bonjour,
    j'ai une question en ce qui concerne l'heritage :
    Voila, J'ai une classe Mere. Cette classe a 2 classes dérivées : Fils et Fille (qui par exemple ont des attributs en plus).

    Je dispose d'une Liste de Mere : static QList<Mere*> liste_mere;

    Et dans cette liste je mets des Fils ou des Filles : liste_mere.append(new Fils(attributs));


    Un peu plus tard dans mon programme j'ai besoin de récupérer les éléments de ma liste, mais je me rends compte qu'ils sont devenus tous des Mere :
    Quand je fais :

    typeid(* liste_mere.at(i)).name() j obtiens "class Mere", comme si il avait été converti.
    Or je j'ai pas envie de les caster après, il faudrait que je puisse savoir en prenant les éléments de la liste-mere si se sont des fils ou des filles.

    Est ce que c est possible ?, est ce que j ai bien expliqué mon problème, et surtout j'ai peur de ne rien avoir compris à l'héritage vu que ca ne marche pas .

    Merci de votre aide !!!

  2. #2
    Expert éminent
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Points : 8 339
    Points
    8 339
    Par défaut
    tes objets sont bien des Fils normalements... puisque ce sont des pointeurs...

    ce que tu veux utiliser ici s'appelle le polymorphisme.

    il y a simplement quelques points auxquels il te faut faire attention :

    Le destructeur de Mere DOIT être déclaré virtual, ainsi que les fonctions que tu veux ensuite éventuellement appeller sur les fils...

    je m'explique au cas où :

    déclarer une méthode virtual implique que la méthode appelée ne sera pas cette méthode là, mais celle correspondant au vrai type... exemple :
    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
    #include <iostream>
    class M
    {
       public :
          virtual void V() { cerr <<"Je suis un M" <<endl; }
          void NV() { cerr <<"Je suis un M" <<endl; }
    };
     
    class F : public M
    {
        public :
          void V() { cerr <<"Je suis un F" <<endl; }  //pas obligatoirement besoin de déclarer virtual ici...
          void NV() { cerr <<"Je suis un F" <<endl; }
    };
     
    int main()
    {
         F* f = new F();
         M* m = f;
         f->V();
         f->NV();
         m->V();
         m->NV();
    }
    normalement, tu devrais voir s'afficher :

    Je suis un F
    Je suis un F
    Je suis un F
    Je suis un M

    j'espère que tu as bien saisie ce qu'était une fonction virtuelle ... en cas, n'hésite pas à demander plus d'explication ^^
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag (en bas)

  3. #3
    Nouveau Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Ok,
    merci de tes eclaircissements, mais je ne pensai pas utiliser le polymorphisme vu que je n ai pas les memes noms de fonctions dans ma classe Mere et dans mes classes Fille et Fils.
    Par contre, pour en revenir a ta première phrase, tu me dis que mes objets sont des Fils normalement vu que ce sont des pointeurs.
    Or quand je fais un cout de typeid( *Mere.at(i)).name()); j obtiens "class Mere " et non "class Fils".
    Encore merci de la rapidite de ta reponse !

  4. #4
    Expert éminent
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Points : 8 339
    Points
    8 339
    Par défaut
    si tu ne stocke que des pointeurs, alors c'est sûrement parce que typeid ne gère pas le polymorphisme justement... étrange, mais je ne vois pas vraiment d'autre explication...

    si a auncun moment tu n'as de copie de tes objets (uniquement des pointeurs), le type réel est conservé...
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag (en bas)

  5. #5
    Nouveau Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    C'est aussi ce que je pensais, mais vu que j'utilise Qt sous Visual studio a mon avis ça doit être une histoire d'options avec le compilateur peut-être.
    Parceque si je veux tester à chaque fois si les objets dans ma liste_mere sont des fils ou des filles je n'ai pas d'autre choix que d'utiliser typeid ?

  6. #6
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Parceque si je veux tester à chaque fois si les objets dans ma liste_mere sont des fils ou des filles
    Mauvaise idée. Voir la FAQ C++ avec comme mot-clé "dynamic_cast".

  7. #7
    Nouveau Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    interessant merci, par contre si j en crois ce qu ils disent on a besoin du dynamic cast dans des cas bien precis, et pour moi c est plutot le cas :

    On n'a pas exploité un éventuel polymorphisme dynamique (utilisation des fonctions virtuelles, voir Que signifie le mot-clé virtual ?).
    On n'a pas exploité un éventuel polymorphisme statique (utilisation des templates et des surcharges).
    On a mal conçu notre hiérarchie.


  8. #8
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Ca dépend. Tu veux connaître le type réel de tes objets pour faire quoi ?

  9. #9
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par beckerfriedman
    typeid(* liste_mere.at(i)).name() j obtiens "class Mere", comme si il avait été converti.
    C'est un peu plus sournois, tu as toujours de bons éléments dans ta liste, mais si tu appelles l'opérateur de déréférencement *, tu transformes ton objet en Mere...

  10. #10
    Nouveau Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    En effet c'est bien vicieux !!!
    Moi en fait je gère un affichage. J'ai une classe Meteo et de cette classe dérivent des classes Foudre, Neige, ... avec juste des attributs en plus pour l'affichage. (la foudre juste des coordonnées, un nuage un diamètre en plus pour le représenter par un cercle, ...).
    Je mets tous ces différents objets dans une liste de Meteo quand je les crée.
    Puis, lorsque je procède à l'affichage un peu plus tard (dans une autre classe qui gère l'affichage) j'ai besoin de récupérer les objets et de savoir si c'est une foudre ou un nuage afin de récupérer les bons champs !!!
    Or , la je me retrouve toujours avec 'class Meteo" ou "class * Meteo" si je n 'utilise pas le * dans typeid.
    Voila, donc je ne pense pas avoir besoin de faire des cast puisque je ne sais pas ce que sont les objets quand je veux les récupérer, j'ai juste besoin de connaitre leur type.

  11. #11
    Nouveau Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    En fait je vais rajouter une même méthode dans chaque classe qui me renvoit le type d'objet que c est puis je fais le dynamic cast.
    Merci a tous en tout cas

  12. #12
    Expert éminent
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Points : 8 339
    Points
    8 339
    Par défaut
    tu devrais plutôt faire une seule méthode qui te retournerais un toutes les infos d'un coup...

    exemple une méthode getCoord qui renverrais une map normalisée (les index sont les même pour toutes les classes filles de Meteo.

    ensuite, tu as juste à parcourir la map avec un itérateur, et tu dessines selon ce qui y est indiqué...

    du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    "x" => 250
    "y" => 300
    "thunder" => 1
    "diameter" => 30
    etc... (j'ai pris une map<string, int> dans ce cas...)

    c'est peut-être pas encore le mieux, tu peux aussi donner toutes les fonctions nécessaires à la classe Meteo, puis ensuite changer le résultat dans les classes filles...

    ces fonctions seraient virtuelles (éventuellement virtuelles pures dans la classe Météo) comme ça tu pourras faire jouer le polymorphisme...

    c'est déjà nettement plus OO et nettement plus propre
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag (en bas)

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    Citation Envoyé par beckerfriedman
    En fait je vais rajouter une même méthode dans chaque classe qui me renvoit le type d'objet que c est puis je fais le dynamic cast.
    Hélas, si tu fais cela, tu ne profites en rien de ce qu'offre l'héritage. De ce que tu décris, tu as effectivement un problème de conception. Beaucoup de chose on déjà été dites dans ce fil, toutes ne sont pas tout à fait exactes d'ailleurs. Rentrer dans le détail rendrait les choses encore plus confuses.
    Si tu continues à programmer en C++, je te conseilles néanmoins de regarder la base d'un cours de programmation objet. Cela te fera gagner un temps précieux.

  14. #14
    Nouveau Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    En fait je pensai faire une methode virtuelle pure getType() dans meteo que je redefinie a chaque fois dans les classes filles me permettant ainsi de trouver le bon type. Cela me semblait assez propre

  15. #15
    Expert éminent
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Points : 8 339
    Points
    8 339
    Par défaut
    non, parce que ça débouche dur un dynamic_cast, ce qui est à éviter le plus possible

    en plus, tu ne devrait pas avoir besoin de connaitre le type réel... tout devrait fonctionner parfaitement avec le type de base et le polymorphisme... sinon c'est qu'il y a éventuellement une erreur de conception
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag (en bas)

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    C'est nécessairement un problème de conception.
    L'héritage sert en premier lieu à découper un problème en niveau d'abstraction.

    Je reprends ton problème de météo (sans en connaître toute l'étendue, bien sûr).
    Imagine que tu aies un premier système basique où soit il fasse soit beau, soit il pleuve.
    Un module est chargé de l'affichage de ces évenement météo. Le beau temps est matérialisé par un disque jaune de rayon plus ou moins grand en fonction de la température
    attendue, et la pluie par une goutte d'eau plus ou moins haute en fonction du volume de précipitation prévu.
    Si je suis ta conception initiale, ce module d'affichage comporte un genre de fonction membre comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    afficher(...)
    {
      pour chaque evenement e:
        si (e est un 'beau temps')
            récupérer la température
            afficher un soleil en fonction de cette température
     
       si (e est un 'pluie')
           récupérer le volume de précipitation
           afficher une goutte en fonction de ce volume
    }
    Ce type de conception est problématique. Elle impose que le module d'affichage détermine le type d'évenement à afficher (c'est le problème que tu rencontres). En d'autre termes, ce module ne peut pas manipuler tous les évenements de manière uniforme.
    Elle est de ce fait peu évolutive. Si on souhaite dans un deuxième temps ajouter un autre évenement, de type brouillard par exemple, qui sera représenté par un carré hachuré plus ou moins dense en fonction de la visibilité, il faudra modifier le module qui gère l'affichage.

    Une solution simple (mais pas unique) est de déléguer la responsabilité de sa représentation à chaque type d'évenement. Le module d'affichage dresse le tableau général, en dessinant une carte de France, plaçant les villes, etc. Et quand vient le moment de placer un signe représentant l'évenement météo, il 'demande' à cet évenement, soit de lui fournir sa représentation graphique, soit de 'se peindre' à un endroit déterminé.
    La fonction d'affichage du module devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    afficher(...)
    {
      pour chaque evenement e
        e.afficher();
    }
    Dans ce cas, on peut faire jouer les mécanismes dhéritage, et notamment la liaison dynamique. Le module d'affichage ne manipules que des évenements météo, sans savoir s'il s'agit de pluie, soleil ou autre. Chacun de ces évènement particuliers hérite d'une classe mère qui impose de posséder une fonction 'afficher'. Cette fonction est redéfinie dans chaque type d'évènement afin d'y fournir sa représentation graphique spécifique.

    Ainsi, le module d'affichage n'a plus besoin de connaître le type réel des évenements qu'il manipule. Du coup, il peut facilement manipuler des listes, vecteurs, tableaux, etc... d'évènements, et l'ajout d'un nouvel évènement (la grêle par exemple) est grandement facilité.

  17. #17
    Membre éclairé Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Points : 871
    Points
    871
    Par défaut
    Moi ce que je comprends pas, c'est pourquoi est-ce que ce serait nécessairement un problème de conception en C++, alors qu'en OCaml, faire ça donne quelque chose de très élégant.

    Imaginez que l'on veuille représenter une expression arithmétique simplement sous forme d'arbre binaire (+, x, -, /).

    En OCaml il aurait été courant d'écrire ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    type expression =
        Feuille of int
    |   Plus of expression * expression
    |   Moins of expression * expression
    |   Fois of expression * expression
    |   Divise of expression * expression;;
    On voit bien que c'est un type récursif, qu'on aurait pu simuler en C++ avec de l'héritage, et des pointeurs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    struct Expression
    {
        virtual ~Expression() {}
    };
     
    struct Feuille : public Expression
    {
        int val;
    };
     
    /* ... */
    Pour évaluer une expression, une petite fonction récursive qui filtre le type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    let rec eval expr = match expr with
        Feuille(i) -> i
    |   Plus(g, d) -> (eval g) + (eval d)
    |   Moins(g, d) -> (eval g) - (eval d)
    |   Fois(g, d) -> (eval g) * (eval d)
    |   Divise(g, d) -> (eval g) / (eval d);;
    Là on cherche toujours le type de l'expression précisément, et c'est plutôt puissant et simple.

    On peut le faire en C++ aussi, avec des typeid ou dynamic cast, mais aussi en donnant une méthode virtuelle à chacunes des structures. On ferait simplement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int evaluer_expression(const Expression* e)
    {
        return e->eval();
    }
    Et là en fait, l'avantage est pas vraiment évident. Ici on a l'impression que le code est plus évolutif, mais à chaque fois c'est du pareil au même.
    On se dit que si l'on rajoute un nouveau type, on aura rien à changer, mais en fait, c'est parce qu'on va déléguer tous nos changements dans la définition de toutes les méthodes virtuelles de la nouvelle classe.

    Dans le cas d'une fonction qui testerait le type de l'objet pointé, il ne suffirait que d'ajouter un cas.

    Bon après, c'est vrai que le C++ ne nous encourage pas à faire ce genre de manipulation, vu la syntaxe plutôt moche. La manière polymorphique du C++ est plus élégante, mais plus lourde, à faire évoluer. On a juste l'avantage du compilateur qui va nous signaler des cas où la méthode virtuelle n'a pas été redéfinie, alors que dans le cas où l'on fait des manipulation connaissant le type, rien, à cause du if-else.

    Mais conceptuellement, c'est la même chose que j'ai fait dans les 2 langages.

    Puis aussi, je n'aime pas la manie de tout intégrer dans des classes, quand parfois ça déforme un peu la vision abstraite du problème.
    Là ça va, mais des fois... ?

  18. #18
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    Je ne suis pas sûr qu'ouvrir un débat philosophique sur les vertues comparées de OCaml et C++ soit le meilleur moyen d'aider un débutant en programmation objet.
    Ensuite, je ne suis pas d'accord avec l'analyse qui en est fait. D'accord pour en débattre, mais pas dans ce fil de discussion.

  19. #19
    Membre éclairé Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Points : 871
    Points
    871
    Par défaut
    Citation Envoyé par Jan Rendek
    Je ne suis pas sûr qu'ouvrir un débat philosophique sur les vertues comparées de OCaml et C++ soit le meilleur moyen d'aider un débutant en programmation objet.
    Ensuite, je ne suis pas d'accord avec l'analyse qui en est fait. D'accord pour en débattre, mais pas dans ce fil de discussion.
    Ah je ne juge pas du tout C++ par rapport à OCaml. Je veux savoir pourquoi en C++ c'est mal vu conceptuellement, alors qu'en OCaml c'est bien vu.
    Puis c'est pas de la philosophie du tout.

  20. #20
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    HanLee > si tu as cette impression, c'est que ton design est mauvais, et c'est là où interviennent les design patterns car si ce que tu disais état vrai, on aurait arrêté de programmer en C++. Il existe des patterns types pour ce problème qui permettent de ne pas avoir à changer toutes les classes filles !

Discussions similaires

  1. Débutant XML
    Par viny dans le forum XML/XSL et SOAP
    Réponses: 8
    Dernier message: 25/07/2002, 12h07
  2. [Kylix] Re Re: débutant sur Kylix et Linux.....
    Par Eclypse dans le forum EDI
    Réponses: 2
    Dernier message: 08/06/2002, 22h53
  3. [Kylix] Le débutant en Kylix et Linux....
    Par Eclypse dans le forum EDI
    Réponses: 2
    Dernier message: 08/05/2002, 10h37
  4. Réponses: 3
    Dernier message: 07/05/2002, 16h06
  5. [HyperFile] 2 questions de débutant
    Par khan dans le forum HyperFileSQL
    Réponses: 2
    Dernier message: 29/04/2002, 23h18

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