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 :

La STL c'est pour le type T


Sujet :

C++

  1. #21
    Membre chevronné
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    349
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 349
    Par défaut
    Je vois pas trop le problème d'utiliser un vecteur de pointeurs, même stupides (pas intelligents quoi ). Mis à part le fait qu'il faut réserver l'utilisation des pointeurs aux cas vraiment nécessaires (polymorphisme, partage de données, etc), il ne faut jamais perdre de vue:

    - Qui crée l'objet pointé?
    - Qui détruit l'objet pointé?
    - La logique du programme permet-elle qu'un objet pointé soit détruit alors qu'il est encore utilisé ailleurs, i.e. rendre un pointeur invalide? (et attention dans les applications multi-thread, une synchronisation de l'accès aux données peut être nécessaire)

    Dans tous les cas, avec les pointeurs, il faut une vision globale pour pas se planter. Et même utiliser des pointeurs intelligents ne nous affranchit pas de devoir réfléchir un peu


    "A chaque new doit correspondre un delete."

  2. #22
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Citation Envoyé par loufoque Voir le message
    La vraie solution c'est std::vector<std::unique_ptr<T>>
    Sauf que ça, c'est du C++0x.

    C'est pour ça qu'en C++03, tu as trois solutions :
    - boost::ptr_vector<T>, la plus efficace
    - std::vector<clone_ptr<T>>, la meilleure à mon goût (mais t'as intérêt à utiliser du COW si tu veux pas des performances desastreuses)
    - std::vector<std::shared_ptr<T>>, qui change la sémantique des objets contenus.
    salut,

    J'ai l'impression que pour sauvegarder le squelette de la STL on est prêt à tous les sacrifices. La prothèse boost peut effectivement parer au nécessaire.

    Pour s'enfoncer dans les rajouts ce qu'il faut préserver c'est le défaut de conception.

    Au fait je ne sais pas comment on déclare un vector< shared_ptr <toto> >

    Il doit y avoir une astuce qui m'échappe.

    De plus le "reference counting" est-il aussi nécessaire qu' opportain ?

  3. #23
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Il faut faire quel #include pour utiliser boost::unique_ptr<> ?

  4. #24
    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 dj.motte Voir le message
    J'ai l'impression que pour sauvegarder le squelette de la STL on est prêt à tous les sacrifices. La prothèse boost peut effectivement parer au nécessaire.
    J'ai donné des argument pour montrer les problèmes de ce que tu as en tête et les avantages de l'approche découplée de la STL.

    Donc, si tu souhaites que je comprenne tes récriminations, il faudrait :
    - Que tu argumentes en quoi un solution à base de pointeur intelligents consitue un sacrifice, qu'est-ce qu'on y perd.
    - Que tu discutes des arguments que j'ai avancé, en quoi ne te conviennent-ils pas, quelle solution proposerais-tu qui te semblerait pérenne.

    Citation Envoyé par camboui Voir le message
    Il faut faire quel #include pour utiliser boost::unique_ptr<> ?
    Ce n'est pas encore disponible, ça fera partie de C++0X, et il faudra inclure <memory>.
    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. #25
    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
    J'ai l'impression que pour sauvegarder le squelette de la STL on est prêt à tous les sacrifices. La prothèse boost peut effectivement parer au nécessaire.
    Non. L'idée est de bénéficier de toute la puissance que nous donne c++. Plutôt que de définir n*m conteneurs "intelligents", ou n est le type de conteneur, et m la stratégie de gestion de la mémoire, on écrit n conteneurs, m "pointeurs" qui gèrent la mémoire, et on utilise la généricité pour demander au compilateur de générer les n*m conteneurs.

    Pour s'enfoncer dans les rajouts ce qu'il faut préserver c'est le défaut de conception.
    STL est considérée comme très bien conçue, je ne connais pas de grosses critiques à son encontre.

    Au fait je ne sais pas comment on déclare un vector< shared_ptr <toto> >
    std::vector<std::shared_ptr<toto> > ?

  6. #26
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 941
    Par défaut
    Citation Envoyé par CedricMocquillon Voir le message
    Moi ce que je trouve dommage avec les conteneurs, c'est qu'il n'y a pas de distinction entre le conteneur et le contenu:
    ce code ne compile pas
    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
     
    #include <vector>
    #include <algorithm>
    #include <iostream>
     
    class A
    {
    private:
      std::vector<int> m_vect;
     
    public:
      A(std::vector<int> const& init) : m_vect(init) {}
     
      std::vector<int> const& f() const throw() { return m_vect; }
    };
     
    int main(void)
    {
      int i = 0;
      std::vector<int> l_vect(10);
      for (i=0; i<10; ++i)
        l_vect[i] = i;
     
      A a(l_vect);
      a.f().front() = 0;
     
      return 0;
    }
    alors que c'est le conteneur que je souhaiterai constant et non son contenu (donc par exemple, pas de possibilité de faire des push_back mais par contre pouvoir modifier ses éléments). Il faut donc passer par le code suivant:
    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 <vector>
    #include <algorithm>
    #include <iostream>
     
    class B
    {
    private:
      std::vector<int*> m_vect;
     
    public:
      B(std::vector<int*> const& init) : m_vect(init) {}
     
      std::vector<int*> const& f() const throw() { return m_vect; }
    };
     
     
    int main(void)
    {
      int i = 0;
      std::vector<int*> l_vect(10);
      for (i=0; i<10; ++i)
        l_vect[i] = new int(i);
     
      B b(l_vect);
      *(b.f().front()) = 100;
      std::cout << *(l_vect[0]) << std::endl;
     
      return 0;
    }
    Cette fois-ci ça compile. J'avais cependant lu il me semble sur ce forum que cela allait évoluer avec la nouvelle norme qui impliquerait alors que les vecteurs de pointeurs constant interdirait alors la modification des éléments pointés (j'espère que ce ne sera pas le cas car il y aura alors complète assimilation entre le conteneur et le contenu qui sont pourtant deux concepts différents)
    Est-ce-que ça ne pourrait marcher 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
     
    class C
    {
    private:
      std::vector<int> m_vect;
     
    public:
      C(std::vector<int> const& init) : m_vect(init) {}
     
      std::vector<int*> const& f() const throw() {
        std::vector<int*> tmp;
        for(vector<int>::iterator it = m_vect.begin(); it!=m_vect.end(); ++it)
            tmp.push_back(&(*it));
        return tmp;
       }
    };
    Si on est prêt à accepter la perte de performance, du moins.

  7. #27
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Oui, le refcounting (ou le COW) ça pue, mais sans sémantique de mouvement, c'est un moindre mal....
    C++0x résout justement ce problème. unique_ptr ne fait PAS de refcounting.

  8. #28
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    Une syntaxe aussi compliquée pour rehausser le squelette de la STL n'en vaut pas la peine.

    Quand les conteneurs de la STL ( std::vector par ex.) ne peuvent plus gérer les pointeurs de manière sérieuse, on vous répond : "allez au bureau A12".

    Au bureau A12 on vous dit :
    -Mais c'est boost, l'Etat qui intervient et qui nous sauve toute nos défauts primaires.

  9. #29
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ce que tu sembles oublier, c'est que même si la STL savait quand deleter un objet pointé, elle ne saurait pas comment. Il n'y a pas qu'une façon de supprimer quelque chose, mais une seule marche sur un objet particulier...

    Bien sûr, il y a déjà delete et delete[]. Mais il y a aussi toutes les mémoires qu'on ne peut pas allouer avec new (genre, la mémoire partagée), à cela s'ajoutent les problèmes de DLL, et les objets à comptage de références intrusif. Tout cela oblige à sortir la sémantique de suppression de la STL.
    Résultat, on utilise des pointeurs intelligents spécifiques, qui non seulement contiennent le "comment", mais gèrent aussi le "quand" en prime...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #30
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Java et C# ont été créés pour les frustrés du C/C++ qui n'aiment pas les free/delete... Enfin il me semble , ne croyez-vous pas ?

  11. #31
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    En C++ on ne fait pas de free ou de delete manuellement quand on veut libérer la mémoire.
    Tout est fait automatiquement par les destructeurs.

  12. #32
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Citation Envoyé par camboui Voir le message
    Java et C# ont été créés pour les frustrés du C/C++ qui n'aiment pas les free/delete... Enfin il me semble , ne croyez-vous pas ?
    Non je suis pas d'accord... En C++ si tu programmes proprement tu évites tout ces cas d'utilisation d'allocation dynamique. En général avec des smart pointeurs. . Plus généralement en utilisant le RAII.

  13. #33
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Citation Envoyé par loufoque Voir le message
    En C++ on ne fait pas de free ou de delete manuellement quand on veut libérer la mémoire.
    Tout est fait automatiquement par les destructeurs.
    Citation Envoyé par Goten Voir le message
    Non je suis pas d'accord... En C++ si tu programmes proprement tu évites tout ces cas d'utilisation d'allocation dynamique. En général avec des smart pointeurs. . Plus généralement en utilisant le RAII.
    C'est ce que je répondrais à ces frustrés, qui ont vécu l'une des deux choses suivantes pour devenir frustrés :
    - Ils n'ont pas pu tomber sur des ressources (livres, articles) leur présentant une bonne façon de programmer en C++
    - Ils n'ont pas pris la peine de se documenter et ont choisi la solution de facilité

    En C++, soit on utilise le RAII, les smart pointers & compagnie, et on ne se soucie plus de la mémoire, soit on utilise des pointeurs "purs et durs" et la responsabilité nous incombe de gérer l'allocation et la désallocation de ces derniers correctement, avec tous les problèmes qui y sont adjoints.

Discussions similaires

  1. Quel est pour vous le meilleur éditeur xml ?
    Par neo.51 dans le forum XML/XSL et SOAP
    Réponses: 87
    Dernier message: 20/02/2010, 20h04
  2. [AC-2000] la constante n'est pas valide pour ce type de contrôle
    Par niko8181 dans le forum IHM
    Réponses: 3
    Dernier message: 20/01/2010, 11h46
  3. Réponses: 5
    Dernier message: 14/11/2009, 01h11
  4. Réponses: 0
    Dernier message: 24/08/2009, 20h30
  5. Réponses: 4
    Dernier message: 05/09/2005, 22h58

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