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 :

Retour covariant : Copie de this.


Sujet :

C++

  1. #1
    Membre éclairé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Par défaut Retour covariant : Copie de this.
    Boujours,
    Je créer une sucession de classe qui éritent en cascaet j'aimerais redéfinir le type de retour de operator++ (int). Maleureusement je ne peut pas utiliser les retour covarian car je doit renvoiller une copie de this avent que les actions de ++ soit éfectuer. Je voudrais savoir si il y a une solution avec les cast.

    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
    38
    39
    40
     
    class A
    {
          virtual inline Point & operator-- ();
          virtual inline Point operator-- (int);
    }
    class B : public A
    {
          virtual inline Point & operator-- ();
          virtual inline Point operator-- (int);
    }
    class C : public B
    {
          virtual inline Point & operator-- ();
          virtual inline Point operator-- (int);
    }
     
    inline A & A::operator++ ()
    {
      x++;
      return *this;
    }
    inline A A::operator++ (int)
    {
      Point ans = *this;
      ++(*this);
      return ans;
    }
     
    inline B & B::operator++ ()
    {
      x++;
      return *this;
    }
    inline B B::operator++ (int)
    {
      Point ans = *this;
      ++(*this);
      return ans;
    }
    Mes articles Développez | Dernier article : Raytracer en haskell
    Network library : SedNL | Zenol's Blog : http://zenol.fr

    N'oubliez pas de consulter la FAQ et les cours et tutoriels.

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Je ne vois pas trop le problème, et le code montré ne m'éclaire pas trop (erreur de simplification ?).

    quel est le problème avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    B & B::operator-- ()
    {
      B* result = this;
      //incremente la valeur
      return result;
    }
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Membre éclairé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Par défaut
    Le problème est avec :
    Je doit renvoiller une copie de this, pas this, car enfaite le corp est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    inline B & B::operator++ ()
    {
      x++;
      return *this;
    }
    inline B B::operator++ (int)
    {
      Point ans = *this;
      ++(*this);
      return ans;
    }
    Le problème est que le type renvoiller(B) n'est pas pareille que le type A. Il semblerais que les retours covariants n'éxiste pas pour les copies d'objet, seulement pour les pointeures.(c'est quelque peut logique).
    Mes articles Développez | Dernier article : Raytracer en haskell
    Network library : SedNL | Zenol's Blog : http://zenol.fr

    N'oubliez pas de consulter la FAQ et les cours et tutoriels.

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Oups, pardon, je n'avais pas les yeux en face des troux.

    Effectivement, le retour est covariant uniquement pour des pointeurs, et operator++ retourne des valeurs.

    D'un autre côté, pour pouvoir utiliser le polymorphisme, il faut aussi utiliser des pointeurs, ce qui rend déjà l'écriture lourde :


    Je me demande si le polymorphisme est utilisé judicieusement dans ton cas, mais il faudrait des noms de classes plus parlants pour savoir. J'ai l'intuition que non, car le polymorphisme se marie bien aux classes d'entité, et les opérateurs arithmétiques se marient bien aux classes de valeur.

    Une idée un peu en l'air comme ça (pas possible de mieux t'aider sans connaître ton design) : Avoir une seule classe qui défini ++, et qui en interne a un pointeur sur une classe polymorphique. Un truc du genre :
    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
     
    class A
    {
      virtual void incremente();
      virtual void clone();
    };
     
    class B : public A {/*...*/};
     
    class AProxy
    {
      A* data;
      AProxy(AProxy const &p) : data(p.data->clone()) {}
      AProxy operator++()
      {
         AProxy result(*this);
         data.incremente();
         return result;
      } 
    }
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Membre éclairé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Par défaut
    Non c'est bien moi qui ai un peut trop simplifier. J'ai éditer pour rajouter ce qui menquais.

    Enfaite voici mes clases:
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    class Point
    {   
          //...
          virtual inline Point & operator++ ();
          virtual inline Point operator++ (int);
     
          double x;
    };
    class Point2d : public Point
    {
          //...
          virtual inline Point2d & operator++ ();
          virtual inline Point2d operator++ (int);
     
          double y;
    };
    class Point3d : public Point2d
    {
          //...
          virtual inline Point3d & operator++ ();
          virtual inline Point3d operator++ (int);
     
          double z;
    };
     
    ////////////////////////////////////////
    ///           Opérateurs             ///
    ////////////////////////////////////////
    inline Abl::Point & Abl::Point::operator++ ()
    {
      x++;
      return *this;
    }
    inline Abl::Point Abl::Point::operator++ (int)
    {
      Point ans = *this;
      ++(*this);
      return ans;
    }
    inline Abl::Point2d & Abl::Point2d::operator++ ()
    {
      x++;
      y++;
      return *this;
    }
    inline Abl::Point2d Abl::Point2d::operator++ (int)
    {
      Point2d ans = *this;
      ++(*this);
      return ans;
    }
    //Prefix ++
    inline Abl::Point3d & Abl::Point3d::operator++ ()
    {
      x++;
      y++;
      z++;
      return *this;
    }
    //Postfix ++
    inline Abl::Point3d Abl::Point3d::operator++ (int)
    {
      Point3d ans = *this;
      ++(*this);
      return ans;
    }
    Mes articles Développez | Dernier article : Raytracer en haskell
    Network library : SedNL | Zenol's Blog : http://zenol.fr

    N'oubliez pas de consulter la FAQ et les cours et tutoriels.

  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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Je ne sais pas dans quel cadre tu utilises tes classes, mais généralement :

    - Les classes de points 1D, 2D, 3D, etc... n'héritent pas les unes des autres, et ne sont pas utilisées polymorphiquement. Principalement pour des raisons de performance, et également parce que c'est inutile dans 90% des applis utilisant des points.

    - Je ne suis pas sûr que l'opérateur ++ ait un sens pour des classes de points autres que 1D.

    - Tu ne pourras jamais utiliser virtual et inline en même temps (l'un est résolu à la compilation, l'autre à l'execution)

  7. #7
    Membre éclairé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Par défaut
    D'accord je peut donc enlever tout mes inline
    Sinon, coment contourner le problème pour simuler un retour covarian? Il y a t'il une solution avec les cast ? Surtout que je risque d'avoir d'autre opérateur surcharger(comme +,-,*,/) qui devront eu aussi retourner des copies.
    Mes articles Développez | Dernier article : Raytracer en haskell
    Network library : SedNL | Zenol's Blog : http://zenol.fr

    N'oubliez pas de consulter la FAQ et les cours et tutoriels.

  8. #8
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Quel est le problème avec ma solution ?

    Autrement, je suis d'accord avec Loulou pour trouver ce design louche. Qu'est-ce que ça t'apporte d'avoir cette dérivation entre tes types de points ? On ne doit pas créer des relations de dérivation entre classes uniquement parce que sur un plan mathématique, ces relations paraissent justifiées. Il faut aussi qu'elles servent à quelque chose.

    Comptes-tu manier des points à partir d'un pointeur dessus sans savoir s'il s'agit d'un point2D ou d'un point3D ? J'ai du mal à voir des scénarios où ça sert à quelquechose.

    Par contre, face à cette situation, je pourrais envisager de vouloir mettre en commun une partie du code de l'implémentation de ces classes. Sûrement quelquechose à base de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template <int n> class PointND {/*...*/};
    typedef PointND<1> Point1D;
    typedef PointND<2> Point2D;
    typedef PointND<3> Point3D;
    Et même ça, j'hésiterai à le faire, car on peut très bien imaginer que les différentes classes de point peuvent avoir des interfaces différentes, et qu'on préfèrerais ne pas fournir à une classe de Point1D des fonctions fournissant les coordonnées en sphérique ou en cylindrique.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  9. #9
    Membre éclairé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Par défaut
    Citation Envoyé par JolyLoic
    Comptes-tu manier des points à partir d'un pointeur dessus sans savoir s'il s'agit d'un point2D ou d'un point3D ?
    Oui!

    Les trois clases auront des methodes comunes, qui retournement le même type, mais qui efectueron des actions diférente selon les dimensions.
    Exemple :
    double SpaceAtO(void)
    Retour x pour Point
    Retourn x*y pour Point2d
    Retourn x*y*z pour Point3d

    Sinon je ne comprend pas bien ce que tu a espliquer plus haut.
    Puije avoir un exemple pour " Point Obj; Obj++ "(je voudrais que du point de vue utilisateur il n'y que ces deux lignes a tapper) ?
    Mes articles Développez | Dernier article : Raytracer en haskell
    Network library : SedNL | Zenol's Blog : http://zenol.fr

    N'oubliez pas de consulter la FAQ et les cours et tutoriels.

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par défaut
    Moi non plus, je ne suis pas convaincu du bien fondé de ce design.

    Néanmoins, si ce que tu souhaites c'est que tes 3 types de points partage un comportement
    commun, alors il suffit de regrouper celui-ci dans une interface dont ces classes hériterons.
    Ca sera toujours mieux que l'héritage en cascade initial

  11. #11
    Membre éclairé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Par défaut
    Oui mais si je fait par exemple Point_Base virtuèl pure, et que toutes mes clases en hérite.
    Point_Base devras définir Point_Base Point_Base::operator ++(); et l'horsque mes autres clases voudrons a leur toure redéfinir l'opérateur ++, il y auras toujours le même problème de type de retoure!

    Sinon JolyLoic tu peut m'espliquer comment je doit utiliser ta solution pour que si l'utilisateur tappe (*MonPoint) = UnPoint++; MonPoint contiène UnPoint avent l'itération ++?

    Sinon je vien d'avoir une autre idée : UnPoint++ retour un struct PointCom[Cet objet seras le même pour toutes mes classes points]
    Et je redéfini l'opérateur d'afectation = pour les objet Point, ce qui permêtras seulement le fonctionement de :
    Point ThePoint;
    Point LePoint;
    ThePoint = Point++;
    Mais ne fonctioneras pas avec les pointeures
    Mes articles Développez | Dernier article : Raytracer en haskell
    Network library : SedNL | Zenol's Blog : http://zenol.fr

    N'oubliez pas de consulter la FAQ et les cours et tutoriels.

  12. #12
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Moi ce que je te conseillerais, c'est de virer ces opérateurs (qui seront de toute façon bien pénibles à utiliser puisque tu vas te trimballer des pointeurs), et de créer à la place des fonctions virtuelles, dont le nom sera plus explicite (parce que ++ sur un point 3D, ça n'a pas de sens mathématiquement parlant).

    Pour ton problème de valeur de retour, je pense que tu peux simplement la virer. Ce qui donnerait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MonPoint->IncrémenteSurX();
    *UnPoint = *MonPoint;
    Après si tu veux vraiment avoir une syntaxe avec plein d'opérateurs surchargés, je pense que tu devrais vraiment oublier ce design à base de polymorphisme.

  13. #13
    Membre éclairé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Par défaut
    Donc quoi qu'il arive, je suprimme le retour... D'acord, ce n'est peutètre pas bien important pour ++. Mais pour Point3d + Point3d ? Comment doije faire pour que ce code fonctione, sans changer le désign de mes classes(c'est que j'y tien a mon désign tordu )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Point3d ShowPoint;
    Point3d Point1;
    Point1.x = 20;Point1.y = 5;Point1.z = 57.3;
    Point3d Point2;
    Point2.x = 6;Point1.y = 8;Point1.z = 1/25;
    ShowPoint = Point1+ Point2;
     
    std::cout << ShowPoint.get_string() << "\n";
    Mes articles Développez | Dernier article : Raytracer en haskell
    Network library : SedNL | Zenol's Blog : http://zenol.fr

    N'oubliez pas de consulter la FAQ et les cours et tutoriels.

  14. #14
    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
    Polymorphisme paramétrique ?
    Il n'y a pas grand intérêt à mélanger des choses différentes comme des points 1D et 3D qui ne seront jamais traités de façon polymorphique ..dynamique.

    Après, on s'en sortira avec:
    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
    template <size_t N> Point {
        double coord[N];
    };
     
    template <size_t N> delta {
        double coords[N];
        // oui, c'est la même définition, mais sémantiquement, ce n'est pas 
        // la même chose => pas d'héritage public!!
    };
     
    template <size_t N>
    Point<N> operator+(Point<N> const& lhs, Delta<N> const& rhs)
    { return Point<N>(lhs) += rhs; };
    // faire la réciproque
     
    template <size_t N>
    Delta<N> operator-(Point<N> const& lhs, Point<N> const& rhs)
    { ... }
    Il peut être intéressant de vraiment isoler les substituabilités pour réduire la quantité de code à pondre tout en permettant un typage fort. Typage fort très utile -- on avait eu des Bugs A La C*n avec une bibliothèque de gestion de dates qui mélangeait allègremlent deltas, GMT, UTC, ... dans une même classe.
    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...

  15. #15
    Membre éclairé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Par défaut
    Citation Envoyé par Luc Hermitte
    Polymorphisme paramétrique ?
    Il n'y a pas grand intérêt à mélanger des choses différentes comme des points 1D et 3D qui ne seront jamais traités de façon polymorphique ..dynamique.

    Après, on s'en sortira avec:
    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
    template <size_t N> Point {
        double coord[N];
    };
     
    template <size_t N> delta {
        double coords[N];
        // oui, c'est la même définition, mais sémantiquement, ce n'est pas 
        // la même chose => pas d'héritage public!!
    };
     
    template <size_t N>
    Point<N> operator+(Point<N> const& lhs, Delta<N> const& rhs)
    { return Point<N>(lhs) += rhs; };
    // faire la réciproque
     
    template <size_t N>
    Delta<N> operator-(Point<N> const& lhs, Point<N> const& rhs)
    { ... }
    Il peut être intéressant de vraiment isoler les substituabilités pour réduire la quantité de code à pondre tout en permettant un typage fort. Typage fort très utile -- on avait eu des Bugs A La C*n avec une bibliothèque de gestion de dates qui mélangeait allègremlent deltas, GMT, UTC, ... dans une même classe.
    Désoler mais:
    paramétrique -> ?
    sémantiquement -> ?
    substituabilités -> 1/2 ?
    un typage fort -> 1/4 ?

    Sinon j'en profiter pour présiser que je dévelope une DLL, hors je me suis vite rendu compte que définir quelque chose de template, c'était dire au compilo de faire les surchages tout seul en fonction des utilisations. Mais comme il s'agit la d'une lib il n'y a aucune utilisation, donc le compilo ne génère aucune surcharge, la fonction disparait litéralement de la dll.
    Mes articles Développez | Dernier article : Raytracer en haskell
    Network library : SedNL | Zenol's Blog : http://zenol.fr

    N'oubliez pas de consulter la FAQ et les cours et tutoriels.

  16. #16
    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 JC_Master
    Désoler mais:
    a- paramétrique -> ?
    b- sémantiquement -> ?
    c- substituabilités -> 1/2 ?
    d- un typage fort -> 1/4 ?

    e- Sinon j'en profiter pour présiser que je dévelope une DLL, hors je me suis vite rendu compte que définir quelque chose de template, c'était dire au compilo de faire les surchages tout seul en fonction des utilisations. Mais comme il s'agit la d'une lib il n'y a aucune utilisation, donc le compilo ne génère aucune surcharge, la fonction disparait litéralement de la dll.
    a- la généricité à base de templates. C'est un polymorphisme statique résolu à la compilation. (d'autres se résolvent à l'édition de lien (géré au niveau des makefile), ou à l'exécution (-> polymorphisme d'inclusion abusivement (comme on dit) appelé juste "polymorphisme")).

    b- sémantique -> le sens des choses. Mélanger point 1D et 3D n'a aucun sens. Le <delta entre deux points>, et un <point> sont deux choses qui ont un sens profondément différent.

    c- C'est au coeur du polymorphisme d'héritage (/inclusion/susbtitution) : un objet d'une classe fille est sencé être substituable à tout objet d'une classe mère qui est attendu. Mis en oeuvre en C++ à l'aide des fonctions virtuelles couplées à l'héritage public.
    EDIT: Je me rends compte que j'avais tapé trop vite et voulais dire autre chose. => "Il s'agit d'isoler les points communs"

    d- Là tu devrais savoir. Il s'agit, p.ex, de ne pas mélanger des objets n'importe comment, surtout quand sémantiquement ils représentent des choses différentes.

    e- Ce n'est pas forcément un problème. Une bibliothèque peut très bien n'être limitée à des fichiers d'en-tête à inclure. Mais si tu as un binaire associé et des fonctions qui attendent des types template en paramètre, alors tu as l'instanciation explicite (si je me souviens bien du nom donné à la chose pour les DLL sous windows). "explicit instanciation" sous MSDN (/google?) normalement.
    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...

  17. #17
    Membre éclairé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Par défaut
    Ok,alors donc :

    1.Comme je l'ai dit un peut plus haut, il est possible que :
    Point3d * Point;

    Et que un peut plus loin dans le programme
    Point = MonPoint2d
    Si on passe dans un plan.
    Ou par exemple on peut donner des point dans un plan, et vouloir les apliquer dans l'espace, en découpen l'espace en divers plan via des Point3d.
    Bon je sias c'est un peut tirer par les cheveux mais bon sa peut ariver.

    2.Pour ce qui est du code template, je ne parle pas(en tout cas pas assé) anglais(Donc pas msdn). Mais j'ai trouver comment instacier une classe template :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    template < typename T >
    class Truc{};
    template Truc<int,char,std::string>;
    Efin je n'arive toujour pas a voire ce que sa done avec mes points? Les deux question est : "esque la syntaxe reste la même [ UnPoint3d = UnPoint2d+ UnPoint1d] ?", et "esque mon désign tordu est conserver?"

    Parce que en regardan atentivement le code, je voi que l'on sépare les deux classes.

    Et pour finir je repose une question que j'avais poser au début : N'y a t'il pas une solution avec les cast ?
    Mes articles Développez | Dernier article : Raytracer en haskell
    Network library : SedNL | Zenol's Blog : http://zenol.fr

    N'oubliez pas de consulter la FAQ et les cours et tutoriels.

  18. #18
    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 JC_Master
    1.Comme je l'ai dit un peu plus haut, il est possible que :
    Point3d * Point;

    Et que un peu plus loin dans le programme
    Point = MonPoint2d
    Si on passe dans un plan.
    Et comment tu détermines la transformation qui va te permettre de projeter ton point sur un plan qui n'est pas xOy, xOz ou yOz ?

    Ou par exemple on peut donner des points dans un plan, et vouloir les appliquer dans l'espace, en découpant l'espace en divers plans via des Point3d.
    Bon je sais c'est un peu tirer par les cheveux mais bon ça peut arriver.
    J'en doute. Les opérations qui tu réaliseras sur un plan ne seront très probablement pas les mêmes que celles réalisées dans un espace.
    Et t'assurer que les points ne seront pas mélangés n'importe comment sera plus un gain qu'autre chose.

    Efin je n'arive toujours pas à voir ce que sa donne avec mes points? Les deux question est : "est-ce que la syntaxe reste la même [ UnPoint3d = UnPoint2d+ UnPoint1d] ?", et "est-ce que mon désign tordu est conserver?"
    o_O Comprends pas.
    Ce qui est sûr est que le design n'est pas à conserver. Si tu veux avoir une base commune de code, passe par les templates.
    Si tu veux passer de 3D à 1D et vice versa, définis-toi les transformations ad'hoc de projection sur droite ou sur plan. Ces changements d'échelles impliquent nécessairement des changements de repère. Tu ne peux pas mélanger tes points juste comme cela. Il te faudrait nécessairement leur adjoindre un contexte précisant le système de coordonnées dans lequel ils se trouvent.

    De plus ces héritages publics me perturbent car un point a une sémantique de valeur, comme toute entité mathématique. C'est à dire que deux points de coordonnées différentes sont différents, et que deux points de mêmes coordonnées sont identiques. "Déplacer" un point consiste en fait considérer un nouveau point autre que le point initial. Si vraiment la notion de déplacement est importante, cela veut dire que tu ne manipules pas des points mais des entités mobiles disposant d'un positionnement, dans l'espace, pouvant changer. On passe à une sémantique d'entités : l'entité qui a été déplacée reste la même entité. C'est son état qui est différent.

    Et pour finir je repose une question que j'avais poser au début : N'y a t'il pas une solution avec les cast ?
    La seule solution (*) pour ré-injecter une sémantique de valeur dans une hiérarchie de classes polymorphiques est d'aller dans la direction que t'as donnée Loïc avec le dit "idiome enveloppe-lettre".
    C'est moyennement compliqué, mais surtout, je reste persuadé que cela ne se justifie pas ici vu qu'un point ne peut pas devenir 1D ou 3D sans adjonction de contexte supplémentaire : origine (coordonnée exprimée dans un espace de dimension N+k (k>0) englobante) plus vecteurs directionnel (on ne dit pas "unitaire" ? Diantre que c'est vieux tout ça) (pour les droites) ou normal (pour les plans).

    (*) car se sont des choses intrinsèquement pas compatibles. Tu as commencé à t'en rendre compte avec le blocaque que tu as exprimé dans ce fil avec la post-incrémentation qui ne pouvait pas renvoyer d'objet du même type dynamique que *this. Dans les faits le blocage est normal et n'est pas génant vu qu'il est 99% du temps symptomatique d'un mauvais design.

    PS: prends le temps de te relire STP.
    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...

  19. #19
    Membre éclairé
    Avatar de Zenol
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 812
    Par défaut
    Citation Envoyé par Luc Hermitte
    PS: prends le temps de te relire STP.
    J'ai encore laisser passer des fautes de frape...

    Bon, je croi que j'ai trouver dans ton poste la plus haute concentration a la phrase carée de mot que je ne comprend pas, donc il est possible que je dise (encore) une ânerie.

    Si je suis ce que tu m'a dit, ce ne sont pas vraiment des points, plutot des contenaires de valeur qui permêtte de faire divers opérations en considérent ces conténères comme des points[Dans divers espaces] ou comme de valeurs. Donc il sagirais donc "d'entités mobiles".

    Pour l'utilisation je pourais soit renvoiller des données, soit pour faire des manipulation dans un plan, soit dans un espaces, soit pour manipuler des valeures comme des points, enfin autent d'utilisation que l'on peut en imaginer.

    Quand je parlais des cast, je pensais a reinterpret_cast, pour par exemple faire un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Point3d PoinFixeDontLaCopieSerasRetourner;
    return reinterpret_cast<Point1d>PoinFixeDontLaCopieSerasRetourner);
    Mes articles Développez | Dernier article : Raytracer en haskell
    Network library : SedNL | Zenol's Blog : http://zenol.fr

    N'oubliez pas de consulter la FAQ et les cours et tutoriels.

  20. #20
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par JC_Master
    Bon, je croi que j'ai trouver dans ton poste la plus haute concentration a la phrase carée de mot que je ne comprend pas,
    Cool, c'est plus dans mon post

    Je vais tenter une analogie pour décrire le point de vue de Luc (ou du moins, le point de vue que je perçois comme étant le sien).

    Une somme d'argent est ce qu'elle est. Elle n'a pas d'état, ne peut pas être modifiée. Une somme de 100€ vaut 100€ et rien d'autre, et ne vaudra jamais rien d'autre. Toute somme de 100€ est égale à toute autre somme de 100€. En C++, on manipulera ce type de données directement (sans pointeur), et on définiera des opérations mathématiques dessus. On appelle ça un type valeur. Il supporte mal le polymorphisme.

    Un compte bancaire possède un état. Il peut contenir à un instant 100€, et à un autre instant 200€, ou plus réalistement -10€. On peut modifier son solde. Copier une telle variable n'a pas de sens. Deux comptes avec le même solde ne sont pas identiques. En C++, on appelle un tel type un type d'entité. On accède en général à ces données par pointeur (plus ou moins intelligent), et il supporte bien le polymorphisme.


    A la limite, si tu as fait de la mécanique, un type avec sémentique valeur serait Point, et un type avec sémentique d'entité serait PointSolide.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

Discussions similaires

  1. petite question (type de retours covariants)
    Par Jabawock dans le forum C++
    Réponses: 6
    Dernier message: 21/08/2007, 08h06
  2. Références croisées et retour covariant
    Par Genjin dans le forum C++
    Réponses: 5
    Dernier message: 19/05/2007, 19h06
  3. Problème de retour covariant
    Par bountykiller dans le forum C++
    Réponses: 4
    Dernier message: 02/11/2006, 00h41
  4. retour de copy
    Par BigNic dans le forum C++
    Réponses: 20
    Dernier message: 06/12/2005, 09h33
  5. [VC++] Comment autoriser les retours covariants ?
    Par Yellowmat dans le forum MFC
    Réponses: 1
    Dernier message: 28/11/2005, 11h46

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