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 :

Avis sur un probl�me de "friend class template"


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre tr�s actif Avatar de metagoto
    Profil pro
    Hobbyist programmateur
    Inscrit en
    Juin 2009
    Messages
    646
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activit� : Hobbyist programmateur

    Informations forums :
    Inscription : Juin 2009
    Messages : 646
    Par d�faut Avis sur un probl�me de "friend class template"
    Lut.

    Dans c++03, la d�claration d'une class friend ne peut pas �tre un type d�pendant. En gros, on ne peut pas faire ceci:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    template<typename T>
    struct A
    {
      // illegal. "T" est un template argument
      friend class T;
    };
    Maintenant si T est lui m�me param�tr� par rapport � A, �a ne va pas arranger les choses.

    Pour comprendre ce que je souhaite faire, voici un code r�duit au minimum, qui fonctionne et qui fait intervenir les bonnes vieilles notions de Car et Engine

    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
    #include<iostream>
    template<typename Engine>
    struct car 
    {
      void start() {
        Engine e;
        e.priv = 1;
        std::cout << e.priv;
      }  
    };
     
    struct engine
    {
      // members...
    private:
      // seul un "car" est sensé instancier un engine
      engine() : priv(0) { }
     
      int priv;
     
      // OK. mais prob: le type "car" est trop spécifique
      template<typename Engine> friend class car;
    };
     
    int main()
    {
      car<engine> c;
      c.start();
      return 0;
    }
    Ce que je souhaiterais faire pour la class engine est ceci:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // pas bon. ridicule.
    // pas bon non plus avec template<template<typename T> class Car>
    template<typename Car>
    struct engine
    {
      // members...
    private:
      engine() : priv(0) { }
     
      int priv;
     
      // illegal. "Car" est un template argument
      template<typename Engine> friend class Car;
    };
    On comprend tout de suite que les types car et engine sont mutuellement corr�l�s et on tombe sur un probl�me de d�claration r�cursive (en plus du probl�me de d�claration du friend).

    Pour contourner le probl�me, j'ai fait ceci:

    - la classe car d�rive d'une class template car_base qui sera friend de engine:
    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
    template<typename Engine>
    struct car_base
    {
      // membres pour accéder à certains membres privates de Engine 
    };
     
    template<typename Engine>
    struct car : public car_base<Engine>
    {
      typedef car_base<Engine> base_type;
      void start() {
        // utilise les membres de base_type pour accéder
        // à l'interface privée de Engine
      }
    };
    - le type param�tr� car_base est d�clar� friend de engine:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    struct engine
    {
      // members...
      // ...
     
      // OK. "car_base" est friend
      template<typename Engine> friend class car_base;
    };
    Je peux maintenant composer avec des types raffin�s tel que advanced_car ou advanced_engine:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template<typename Engine>
    struct advanced_car : public car_base<Engine>
    { 
      // ..
    }
     
    advanced_car<engine> ac;
     
    car<advanced_engine> aac;
     
    advanced_car<advanced_engine> aaac;
    En conclusion, Car peut varier ind�pendamment de Engine. La contrainte est que Engine reste compatible avec la fa�ade que constitue car_base.

    Tout ceci est destin� � �tre utilis� dans un context plus vaste bas� sur les policies. Je me fiche que advanced_car ne d�rive pas de car dans l'exemple.

    Est-ce que ce "trick" de la base classe param�tr�e qui sera friend de son param�tre vous parait pertinent. Une autre solution ?

  2. #2
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par d�faut
    Pourquoi ne remplaces-tu pas simplement :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
      // OK. mais prob: le type "car" est trop spécifique
      template<typename Engine> friend class car;
    par :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
      // OK. mais prob: le type "car" est trop spécifique
      friend class car<engine>;
    Si j'ai bien compris, seule car est param�tr�e, pas engine, donc tu n'es pas dans le premier cas que tu d�cris (o� tu dois d�clarer friend le param�tre template).

  3. #3
    Membre tr�s actif Avatar de metagoto
    Profil pro
    Hobbyist programmateur
    Inscrit en
    Juin 2009
    Messages
    646
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activit� : Hobbyist programmateur

    Informations forums :
    Inscription : Juin 2009
    Messages : 646
    Par d�faut
    @white_tentacle

    Je ne suis pas dans le "premier cas" (o� je dois d�clarer friend le param�tre template) car je ne m'en sort pas sinon. Id�alement c'est ce que j'aimerai mais on tombe dans une situation o� les 2 types sont param�tr�s l'un par rapport � l'autre (sans que l'on soit dans un CRTP) et il y a bien sur le fait que "friend" ne fonctionne pas avec un type param�tre.

    Sinon pour la suggestion:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    friend class car<engine>;
    En fait �a serait la solution la plus simple, effectivement. Sauf que je souhaite que la classe engine puisse fonctionner avec n'importe quel car. Je ne peux/veux pas "hard coder" la classe car en tant que friend.

    Du coup, je passe par cette base class car_base. J'acc�pte de "hard coder" car_base dans les classes Engine. Du coup l'interface de car_base manipul�e par les classes qui en h�ritent (les car) constitue le "point d'invariance" (ou de compatibilit�) entre un Engine et un Car. Tout le reste est laiss� libre et c'est ce que je souhaite car il s'agit de "composer" dans un cadre de policies. Je ne sais pas si je me fais bien comprendre

  4. #4
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par d�faut
    Je crois que j'ai compris. Effectivement, je ferais comme �a (il me semble que c'est ce que tu d�cris) :

    dans engine, on d�clare comme classe amie car_base.

    Dans car_base, j'impl�mente des wrapper qui permettent d'acc�der aux propri�t�s de engine que je veux modifier (et uniquement �a).

    Puis, pour chacun de mes car, je fais un h�ritage priv� ou prot�g� (mais pas public, pour ne pas �tre polymorphique) de car_base. Dans car, j'utilise les wrapper de car_base pour modifier les propri�t�s de engine.

    Le sch�ma peut �tre sym�trique si engine doit modifier des propri�t�s de car, mais �a voudrait dire que tu as un couplage tr�s (trop) fort entre tes deux classes.

  5. #5
    Membre tr�s actif Avatar de metagoto
    Profil pro
    Hobbyist programmateur
    Inscrit en
    Juin 2009
    Messages
    646
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activit� : Hobbyist programmateur

    Informations forums :
    Inscription : Juin 2009
    Messages : 646
    Par d�faut
    Merci white_tentacle, tu as parfaitement compris.

    Par chance (ou par un design judicieux ), le sch�ma n'a pas � �tre sym�trique (Engine n'a pas besoins de manipuler Car).

    Je ne sais pas si ce "design pattern" porte un nom.

  6. #6
    Membre Expert

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 49
    Localisation : France, Bouches du Rh�ne (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - Op�rateur de t�l�communications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par d�faut
    Citation Envoy� par metagoto Voir le message
    Je ne sais pas si ce "design pattern" porte un nom.
    Une erreur ?

    En gros, tu est en train de nous expliquer que
    * soit seules les car ont le droit de manipuler l'interface des engine
    * soit tu autorises les car � manipuler l'int�rieur des engine.

    Ni l'une ni l'autre de ces possibilit� n'a de chance d'�tre valide en termes d'architecture logicielle. Si engine existe et d�fini une interface publique, alors �a veut dire que tout le monde peut utiliser un engine : une instance de car, mais aussi un m�canicien ou un banc de test. Si engine ne d�finit pas d'interface publique, alors engine n'a pas � exister en tant que classe (une classe fournit des services; si elle ne fournit pas de service, c'est qu'elle ne fait rien).

    Maintenant, si ton design repose sur le fait que jamais rien d'autre qu'une instance de car ne manipulera un engine, alors tu peux peut-�tre faire de engine une inner-class de car.

    Autre solution : si car n'a besoin que d'une partie des services offerts par engine (et que, d'un autre cot�, d'autres classes peuvent utiliser d'autres services de engine), alors il manque peut �tre un niveau d'indirection � ton design - des adapteurs probablement (car_engine_adapter, ...). Ce qui ne veut pas dire que engine ne doit pas exposer l'int�gralit� des services qu'elle offre � ses diff�rents clients.
    [FAQ des forums][FAQ D�veloppement 2D, 3D et Jeux][Si vous ne savez pas ou vous en �tes...]
    Essayez d'�crire clairement (c'est � dire avec des mots fran�ais complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Caf�. C'est d�pass� tout �a.
    Et si vous �tes sages, vous aurez peut �tre vous aussi la chance de passer � la t�l�. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

Discussions similaires

  1. Friend Classe Template
    Par coberle dans le forum C++
    R�ponses: 5
    Dernier message: 29/03/2013, 13h19
  2. Besoin de votre avis sur un probl�me
    Par petitcoucou31 dans le forum Langage
    R�ponses: 7
    Dernier message: 30/06/2008, 16h33
  3. R�ponses: 24
    Dernier message: 11/06/2008, 15h26
  4. Probl�me avec vector de classe template :(
    Par coyotte507 dans le forum Langage
    R�ponses: 7
    Dernier message: 16/04/2008, 12h40
  5. Avis sur gros probl�me BDE en Reseau
    Par tipiweb dans le forum Bases de donn�es
    R�ponses: 4
    Dernier message: 29/04/2005, 09h25

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