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

Ada Discussion :

Problème de généricité de type privé


Sujet :

Ada

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 98
    Par défaut Problème de généricité de type privé
    Bonjour à tous,

    voilà j'ai une package nommé Liste_Gen fournissant une liste generique avec comme parametre formel generique un type d'element. Liste_Gen a aussi des fonctions generiques qui traite les elements de la liste (Affichage,etc...).
    J'aimerais l'utiliser dans un package Voiture pour creer une liste de voiture. J'utilise un type privée TVoiture (TVoiture est un record). Lors de l'instanciation, je fais:
    package listeVoiture is new Liste_Gen(TVoiture);
    Le probleme est que cette instanciation ne fonctionne pas, car TVoiture est privé ! Or j'ai des fonctions generic d'acces sur TVoiture comme par exemple
    AfficherListeVoiture (Tvoiture). Donc je ne peux pas instancier le package Liste_Gen dans le private !
    Voilà, en espérant que vous ayez compris, pourriez-vous m'aider svp ???
    D'avance merci.
    A bientot.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    PACKAGE PVoiture IS 
     
       TYPE TVoiture IS PRIVATE;
     
       --liste qui pose probleme
       package ListeVoiture is new Liste_Gen(TVoiture) 
     
       ...
       --fonctions generiques instanciées (du package Liste_Gen) qui utilisent TVoiture
       ...
     
    PRIVATE 
       Type Tvoiture is record
         ...

  2. #2
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Par défaut
    Bienvenue chez nous

    List_Gen.ads:
    Code Ada : 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
     
    generic
     
        type Element_Type is private;
     
    package List_Gen is
     
        type List_Node; -- Definition is forwarded
        type List_Node_Reference is access List_Node;
     
        type List_Node is
        record
            Content : Element_Type;
            Next : List_Node_Reference;
        end record; -- List_Node
     
        subtype List_Type is List_Node;
     
        -- Some other methods comes here
     
    end List_Gen;

    PVoiture.ads:
    Code Ada : 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
     
    with List_Gen;
     
    package PVoiture is
     
        type Voiture_Type is private;
        type Voiture_List is private;
     
        procedure AfficherList (List : in Voiture_List);
     
    private
     
        type Voiture_Type is
        record
            null;
        end record; -- Voiture_Type
     
        package Voiture_List_Package is new List_Gen (Voiture_Type);
        type Voiture_List is new Voiture_List_Package.List_Type;
     
    end PVoiture;

    Il est tout à fait possible d'avoir un Voiture_Type private, tout en définissant dans la partie publique une procedure dépendante de Voiture_List, à condition que Voiture_List soit private également, car pour définir Voiture_List, Voiture_Type doit être définie concrêtement. Donc si la définition concrête de Voiture_List doit venir aprés la définition concrête de Voiture_Type, cela signifie que la définition concrête de Voiture_List sera trouvera aprés celle de Voiture_Type dans la partie private. Et comme Voiture_List doit être définie concrêtement dans la partie private, alors il ne peut apparaître dans la partie publique, que comme type privé.

    Oilà

    Est-ce que cette organisation peut répondre à tes spécifications ?

    Bonne journée

  3. #3
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 98
    Par défaut
    Merci beaucoup cela resoud mon probleme en partie
    J'ai un autre souci, au niveau des instanciations de fonctions generiques. Par exemple, si j'ai une fonction generique AfficheListe dans mon package List_Gen. Il va me falloir instancier la fonction AfficheListe en lui passant en parametre une fonction qui affiche un objet de type TVoiture (cette fonction je l'aurais bien sur au préalable créé).
    Or l'instanciation du paquetage List_Gen se faisant en private, je suis obligé d'instancier les fonctions generiques aussi en private ! Et donc ces fonctions seront inutilisables, a par si je creer d'atre fonctions pbliques qui executent les fonctions en private...

    Dans mon package List_Gen:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    generic
            --affichage d'un element
            with procedure AfficherElement(e:telement);
            --affiche la liste
            procedure AfficherListe (P : in TListe);
    Dans mon package Voiture:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    PUBLIC
     
    procedure AfficherListeVoiture is new AfficherListe(AfficherVoiture)
    --ici AfficherListe est inconnu car l'instanciation de List_Gen est faite en privée
     
    PRIVATE
    Type Tmachine is record 
    ....
     
    package Voiture_List_Package is new List_Gen (Voiture_Type);
    type Voiture_List is new Voiture_List_Package.List_Type;

  4. #4
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Par défaut
    Citation Envoyé par dr_octopus74 Voir le message
    Par exemple, si j'ai une fonction generique Affiche_Liste dans mon package List_Gen.
    D'accord. Donc tu as une procédure Affiche_List, qui, nous le supposont, appel itérativement une procédure Affiche_Element sur tout les éléments de la liste.

    Affiche_List est donc une procedure du package générique, et Affiche_Element sera un paramètre du package générique List_Gen.

    Citation Envoyé par dr_octopus74 Voir le message
    Il va me falloir instancier la fonction Affiche_List
    Pourquoi instancier la procédure Affiche_List ? ... puisque qu'elle est instanciée en même temps que l'instanciation du package.

    Ce n'est pas Affiche_List qui est générique, mais le package qui la contient (elle a une dépendence générique, mais n'est pas déclarée de manière générique). Le package est générique, mais la déclaration de Affiche_List n'a pas besoin de l'être.

    Citation Envoyé par dr_octopus74 Voir le message
    en lui passant en parametre une fonction qui affiche un objet de type TVoiture (cette fonction je l'aurais bien sur au préalable créé).
    On oublie ce paramètre, pour les raisons invoquée précédement, et on passe ce paramètre au package.

    Citation Envoyé par dr_octopus74 Voir le message
    Or l'instanciation du paquetage List_Gen se faisant en private,
    Oui, tu ne dois pas confondre l'implementation est la déclaration. Tu peux déclarer une fonction Affiche_Voiture_List et indiquer qu'elle prend en paramètre un argument du type Voiture_List.

    Tu aura également défini une fonction Affiche_Voiture.

    Dans la section privée, tu instancie List_Gen en lui ajoutant le nouveau paramètre Affiche_Voiture.

    L'instanciation de List_Gen produira une fonction Affiche_List s'appliquant à Voiture_List.

    Et comme l'implementation peut accéder à la section privée, l'implementation de Affiche_Voiture_List reposera sur Voiture_List_Package.Affiche_List.

    C'est ce que l'on appel un "wrapper". On appel wrapper (*), de manière général, tout ce qui sert à "envelopper" une chose qui ne doit pas ou ne peut pas être visible. Et au lieu de se reférerer directement à cette chose invisible, on se réfère à ce qui l'enveloppe.

    • (*) Wrapper, est un mot anglais signifiant "emballer" ou "contourner".


    On procède comme suit :
    1. Déclaration de la signature d'une fonction, dont l'implémentation repose sur une chose invisible. On peut, ce n'est que la déclaration.
    2. Dans une zone invisible (ici, la section privée), on cré une chose invisible (ici la procedure Affiche_List de Voiture_List_Package).
    3. L'implémentation de la fonction déclarée en (1), repose sur la fonction invisible crée en (2).


    Le résultat est que par l'intermédiaire de la fonction déclaré en (1), on accède à la fonction déclarée en (2).

    C'est une technique trés fréquente, et qui sert dans de nombreuses interface logicielle. C'est une technique que je te recommande de mettre en bonne place dans ton petit carnet.

    Oilà

    Est-ce que ça va ?

    List_Gen.ads:
    Code Ada : 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
     
    generic
     
        type Element_Type is private;
        with procedure Affiche_Element (Element : in Element_Type);
     
    package List_Gen is
     
        type List_Node; -- Definition is forwarded
        type List_Node_Reference is access List_Node;
     
        type List_Node is
        record
            Content : Element_Type;
            Next : List_Node_Reference;
        end record; -- List_Node
     
        subtype List_Type is List_Node;
     
        -- Some other methods comes here
     
        -- Affiche_List invoks Affiche_Element
        procedure Affiche_List (List : in List_Type);
     
    end List_Gen;

    PVoiture.ads:
    Code Ada : 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
     
    with List_Gen;
     
    package PVoiture is
     
        type Voiture_Type is private;
        type Voiture_List is private; -- A list of Voiture_Type
     
        procedure Afficher_Voiture (Voiture : in Voiture_Type);
        procedure Afficher_List_Voiture (List : in Voiture_List);
     
    private
     
        type Voiture_Type is
        record
            null;
        end record; -- Voiture_Type
     
        package Voiture_List_Package is new List_Gen (
            Voiture_Type,
            Afficher_Voiture);
     
        type Voiture_List is new Voiture_List_Package.List_Type;
     
        -- Implementation for Afficher_List_Voiture relies on
        -- Voiture_List_Package.Affiche_List
     
    end PVoiture;

  5. #5
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 98
    Par défaut
    Franchement merci bcp pour ton aide !


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Affiche_List est donc une procedure du package générique, et Affiche_Element sera un paramètre du package générique List_Gen.
    En fait, lorsque j'instancie le package List_Gen, je ne passe en parametre que le type d'element (ici Tvoiture). Ce n'est qu'apres ou j'instancie une fontion genrique d'affichage de liste.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    generic
            --affichage d'un element
            with procedure AfficherElement(e:telement);
            --affiche la liste
            procedure AfficherListe (P : in TListe);
    Mais bon ce n'est pas grave ça...

    Par conre, les 2 pragraphes ci-dessous me chagrinent un peu:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    -- Implementation for Afficher_List_Voiture relies on
    -- Voiture_List_Package.Affiche_List
    Et comme l'implementation peut accéder à la section privée, l'implementation de Affiche_Voiture_List reposera sur Voiture_List_Package.Affiche_List
    Justement, ou est l'instanciation de Affiche_List avec Affiche_Voiture?? Autrement dit, comment est créé Affiche_Voiture_List?? Tu es d'accord avec moi qu'il ne faut pas re-ecrire completement Affiche_Voiture_List ??? (car elle est deja sous forme generique dans le package List_Gen)

    Merci d'avance

  6. #6
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Par défaut
    Citation Envoyé par dr_octopus74 Voir le message
    Justement, ou est l'instanciation de Affiche_List avec Affiche_Voiture?? Autrement dit, comment est créé Affiche_Voiture_List?? Tu es d'accord avec moi qu'il ne faut pas re-ecrire completement Affiche_Voiture_List ??? (car elle est deja sous forme generique dans le package List_Gen)

    Merci d'avance
    Non, tu ne la re-écris pas, mais tu écris une procédure qui appel sont implémentation :

    Code Ada : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    procedure Affiche_Voiture_List (List : Voiture_List) is
    begin
        Voiture_List_Package.Affiche_List (List);
    end;

    Tu vois ?

    Tu écris quelque chose, bien sûr, mais tu ne re-écris pas l'implementation, tu ne fais que l'appeler : c'est un "wrapper".

    Note: je t'ai présenté les choses en prennant ta présentation des choses comme point de départ. Mais il existe peut-être d'autres manières de le faire. Je me pencherai sur la question dès que j'aurai le temps, et je te l'écrirai ici.

    Ce qui "complique" les choses ici, c'est surtout le fait que le type Voiture_Type soit privé. Pour quelles raisons doit-il être privé ?


    Bonne soirée

Discussions similaires

  1. Problème udpate avec un type Date
    Par kevinp dans le forum Général Dotnet
    Réponses: 3
    Dernier message: 17/05/2006, 06h09
  2. Balise form - problème attributs name et type
    Par michihala dans le forum Struts 1
    Réponses: 3
    Dernier message: 03/04/2006, 17h17
  3. Problème de requete avec type monétaire
    Par Pymm dans le forum ASP
    Réponses: 11
    Dernier message: 09/09/2005, 16h57
  4. [Ada 95] Généricité de type/package
    Par kindool dans le forum Ada
    Réponses: 5
    Dernier message: 19/05/2005, 11h54
  5. Problème de champs Paradox type : mémo formaté
    Par mjp dans le forum Bases de données
    Réponses: 6
    Dernier message: 05/04/2005, 21h13

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