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 :

Demande d'avis sur des pointeurs intelligents


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Mars 2006
    Messages
    209
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 209
    Par défaut Demande d'avis sur des pointeurs intelligents
    Bonjour à vous tous !!.

    J’espère que vous allez bien, et que pour ceux qui ont passé le bac ont réussis et qu'ils ont obtenus les vœux souhaité.

    Si je viens vous voir, ce n'est pas spécialement pour vous demander de l'aide (pour une fois (a) ), mais bien pour avoir un avis sur mon code.

    Je viens du langage C (langage que j'apprécie beaucoup, donc pas de troll le C c'est pourri ^^ ), mais j'ai envie d'apprendre du C++. D'après ce que j'ai vu, ce "passage" peut donner de mauvaises habitudes, etc etc, donc je veux savoir si je code dans un C++ correct ou vraiment super moche horrible (n'hésitez pas à le dire, c'est comme ça qu'on progresse ).

    Bref, je ne suis pas là pour vous présentez du code super optimisé, mais juste un code sécurisé, en fait j'ai décider de "reprendre" l'idée des auto_ptr et de les "améliorer". Donc l'idée est simple, le pointeur peut se faire copier, je gère le nombre de référence etc etc. J'ai corriger toutes mes erreurs que j'ai put trouver à l'aide de valgrind, donc je pense qu'il est fonctionnel.

    A part pour les itérateurs, que j'ai implémenter à la one again et bistoufly (car je n'en suis pas encore aux itérateurs en fait), je pense que j'ai fait du travail plus ou moins correct.

    J'ai essayer d'imiter le plus possible le comportement d'un pointeur : Opérateur * -> [] ++ -- post et préFixé, += -=, + - etc.

    Voilà mon code, si vous trouvez des erreurs, segfault, fuites de mémoires, merci de me le dire.

    main.cpp
    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
    67
    68
    69
    70
    71
    72
    73
    #include <iostream>
     
    #include "QGM_Ptr.h"
     
    using namespace std;
     
    int main(void)
    {
        qgm::smart_ptr<int> tableau(100);
     
        qgm::smart_ptr<int> pointeurSurLaPremiereCase;
        qgm::smart_ptr<int> ptr;
     
        pointeurSurLaPremiereCase = tableau;
     
        for(int i = 0; i < 102; ++i){
        	try{
    	    *tableau++ = i;
     	}
     
    	catch(exception &e){
    	    cout << e.what() << endl;
    	}
        }
     
        for(int i = 0; i < 102; ++i){
        	try{
    	    cout << pointeurSurLaPremiereCase[i] << " ";
        	}
     
        	catch(exception &e){
    	    cout << e.what() << endl;
        	}
        }
     
        try{
     	// Pointeur = première case du tableau 
       	ptr = -100 + tableau;
     
      	// On affiche
       	cout << endl << *ptr << endl;
        }
     
        catch(exception &e){
    	cout << e.what() << endl;
        }
     
        // On supprime
        ptr.release();
     
        // Doit affiche qgm::bad_ptr
     
        try{
    	    cout << *pointeurSurLaPremiereCase << " ";
        }
     
        catch(exception &e){
      	cout << e.what() << endl;
        }
     
        ptr.alloc(200);
        tableau = ptr;
     
        qgm::smart_ptr<int>::iterator it = tableau.begin();
     
        for(; it != tableau.end(); ++it)
    	*it = 0;
     
        for(it = ptr.begin(); it != ptr.end(); ++it)
            cout << *it << " ";
     
        return 0;
    }
    QGM_types.h
    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
    #ifndef QGM_TYPES_H_INCLUDED
    #define QGM_TYPES_H_INCLUDED
     
    namespace qgm{
        typedef signed char    s8;
        typedef unsigned char  u8;
     
        typedef signed short   s16;
        typedef unsigned short u16;
     
        typedef signed long    s32;
        typedef unsigned long  u32;
     
        typedef signed int     sint;
        typedef unsigned int   uint;
     
        typedef float          f32;
        typedef double         f64;
    }
     
    #endif // QGM_TYPES_H_INCLUDED
    qgm_ptr (le plus important haha)
    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
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    #ifndef QGM_PTR_H_INCLUDED
    #define QGM_PTR_H_INCLUDED
     
    #include <map>
    #include <exception>
    #include <string>
    #include "QGM_Types.h"
     
    namespace qgm
    {
        class bad_ptr : public std::exception
        {
            public :
                bad_ptr(void) throw() : p("qgm::bad_ptr"){}
     
                virtual char const *what(void) const throw(){
                    return p.c_str();
                }
     
                virtual ~bad_ptr(void) throw(){}
     
            private :
                std::string p;
        };
     
        class out_of_range_ptr : public std::exception
        {
            public :
                out_of_range_ptr(void) throw() : p("qgm::out_of_range_ptr"){}
     
                virtual char const *what(void) const throw(){
                    return p.c_str();
                }
     
                virtual ~out_of_range_ptr(void) throw(){}
     
            private :
                std::string p;
        };
     
        template<typename Type>
        class smart_ptr{
            /** Class gérant les pointeurs alloués sur le tas **/
     
            public :
                /** Ce constructeur permet d'avoir accès à un tableau dynamique
                        de taille définie **/
                explicit smart_ptr(u32 size);
     
                /** Construit un pointeur intelligent à partir d'un pointeur.
                        Si isArrayNelem == 0 : Le pointeur est alloué avec new
                        Si isArrayNelem >= 1 : Le pointeur est alloué avec new[]
                            et contient le nombre de "cases préallouées"
                    De base, on alloue avec new **/
                smart_ptr(Type *ptr, u32 isArrayNelem = 0);
     
                /** Constructeur de copie **/
                smart_ptr(smart_ptr const &ptr);
     
                /** Opérateur d'affection **/
                smart_ptr &operator=(smart_ptr const &ptr);
     
                /** Construit un pointeur NULL **/
                smart_ptr(void);
     
                /** Définie pour struct->membre **/
                Type *operator->(void);
     
                /** int i = *(int*)pInt; **/
                Type &operator*(void);
     
                /** int n = tableau[5]; **/
                Type &operator[](s32 index);
     
                /** Operateur += et -=  **/
                smart_ptr &operator+=(s32 i);
                smart_ptr &operator-=(s32 i);
     
                /** Opérateur d'incrémentation préFixé **/
                smart_ptr &operator++(void);
                smart_ptr &operator--(void);
     
                /** Opérateur d'incrémentation postFixé **/
                smart_ptr operator++(sint);
                smart_ptr operator--(sint);
     
                /** Permet d'allouer le pointeur **/
                void alloc(u32 size = 1);
     
                /** Permet de libérer le pointeur **/
                void release(void);
     
                /** Destructeur **/
                ~smart_ptr(void);
     
     
    	    /** Les itérateurs **/
    	    typedef Type* iterator;
     
    	    Type *begin(void){return m_Begin;}
    	    Type *end(void)  {return m_End;  }
     
            private :
                Type *m_Ptr;
                Type *m_Begin;   // Pointeur poinant sur le premier élément
                Type *m_End;     // Pointeur sur l'élément suivant le dernier
                bool  m_IsArray; // Est ce que le tableau est alloué avec new([])
     
                /** Remet à 0 l'objet **/
                void setZero(void);
     
                /** Retire une référence et détruit le pointeur si besoin **/
                void subPtr(void);
     
                /** Test le pointeur **/
                void testPointer(void);
        };
     
        /** Tableau associatif pour clé un pointeur
                et comme valeur le nombre de référence à ce pointeur **/
        static std::map<void*, u32> ptrMap;
     
        typedef std::map<void*, u32>::iterator iteratorPtrMap;
     
        template<typename Type>
        void smart_ptr<Type>::setZero(void){
            m_Ptr = m_Begin = m_End = 0;
            m_IsArray = false;
        }
     
        template<typename Type>
        void smart_ptr<Type>::subPtr(void){
            iteratorPtrMap it = ptrMap.find(m_Begin);
     
            /** si le pointeur existe **/
            if(it != ptrMap.end()){
                if(--it->second == 0){ // Si il n'est plus utilisé on supprime
                    ptrMap.erase(it);
     
                    if(m_IsArray == true)
                        delete[] m_Begin;
     
                    else
                        delete   m_Begin;
     
                    setZero(); // On remet = 0 le pointeur
                }
            }
        }
     
        template<typename Type>
        void smart_ptr<Type>::testPointer(void){
            iteratorPtrMap it = ptrMap.find(m_Begin);
     
            // si le pointeur n'est pas trouvé, on lève une exception
            if(it == ptrMap.end())
                throw bad_ptr();
        }
     
        /** Constructeurs **/
        /** Constructeur NULL **/
        template<typename Type>
        smart_ptr<Type>::smart_ptr(void) :
        m_Ptr(0),
        m_Begin(0),
        m_End(0),
        m_IsArray(false){
        }
     
        /** Constructeur récupérant un pointeur **/
        template<typename Type>
        smart_ptr<Type>::smart_ptr(Type *ptr, u32 isArrayNelem) :
        m_Ptr(ptr),
        m_Begin(ptr),
        m_End(ptr + (isArrayNelem == 0 ? 1 : isArrayNelem)),
        m_IsArray(isArrayNelem == 0 ? false : true){
            /** Si ce n'est pas un tableau **/
            if(isArrayNelem == 0)
            {
                m_End = ptr + 1;
                m_IsArray = false;
            }
     
            else
            {
                m_End = ptr + isArrayNelem;
                m_IsArray = true;
            }
     
            ptrMap[m_Begin] = 1; // une utilisation
        }
     
        /** Constructeur allouant une certaines place **/
        template<typename Type>
        smart_ptr<Type>::smart_ptr(u32 size):
        m_Ptr(new Type[size]),
        m_Begin(m_Ptr),
        m_End(m_Ptr + size),
        m_IsArray(true){
            ptrMap[m_Begin] = 1; // une utilisation
        }
     
        /** Constructeur de copie **/
        template<typename Type>
        smart_ptr<Type>::smart_ptr(smart_ptr const &ptr) :
        m_Ptr(ptr.m_Ptr),
        m_Begin(ptr.m_Begin),
        m_End(ptr.m_End),
        m_IsArray(ptr.m_IsArray){
            iteratorPtrMap it = ptrMap.find(m_Begin);
     
    	/** Si le pointeur existe **/
    	if(it != ptrMap.end())
    	    ++it->second;
        }
     
        /** Opérateur = **/
        template<typename Type>
        smart_ptr<Type> &smart_ptr<Type>::operator=(smart_ptr const &ptr){
            if(m_Ptr == ptr.m_Ptr)
                return *this;
     
            subPtr();
     
            m_Ptr   = ptr.m_Ptr;
            m_Begin = ptr.m_Begin;
            m_End   = ptr.m_End;
     
            m_IsArray = ptr.m_IsArray;
     
            if(m_Ptr != 0)
                ++ptrMap[m_Begin]; // On ajoute une utilisation
     
            return *this;
        }
     
        /** Fonctions d'allocations / désallocations **/
        template<typename Type>
        void smart_ptr<Type>::alloc(u32 size)
        {
            /** Si on cherche à allouer mais que c'est déjà pris **/
            subPtr();
     
            m_Ptr = new Type[size];
            m_Begin = m_Ptr;
            m_End = m_Ptr + size;
            m_IsArray = true;
        }
     
        template<typename Type>
        void smart_ptr<Type>::release(void){
            iteratorPtrMap it = ptrMap.find(m_Begin);
     
            if(it == ptrMap.end())
                return;
     
            else{
                if(m_IsArray == true)
                    delete[] m_Begin;
     
                else
                    delete m_Begin;
            }
     
            setZero();
            ptrMap.erase(it);
        }
     
        /*************************************************************************/
        /** Opérateurs * -> [] **/
     
        template<typename Type>
        Type &smart_ptr<Type>::operator*(void){
            testPointer();
            return *m_Ptr;
        }
     
        template<typename Type>
        Type *smart_ptr<Type>::operator->(void){
            testPointer();
     
            if(m_Ptr < m_Begin || m_Ptr >= m_End)
                throw out_of_range_ptr();
     
            return *m_Ptr;
        }
     
        template<typename Type>
        Type &smart_ptr<Type>::operator[](s32 index){
            testPointer();
     
            Type *ptr = m_Ptr + index;
     
            if(ptr < m_Begin || ptr >= m_End)
                throw out_of_range_ptr();
            return *ptr;
        }
     
        /** Operateur += et -=  **/
        template<typename Type>
        smart_ptr<Type> &smart_ptr<Type>::operator+=(s32 i){
            testPointer();
     
            Type *ptr = m_Ptr + i;
     
            /** Le pointeur à le droit de pointé sur m_End **/
            if(ptr < m_Begin || ptr > m_End)
                throw out_of_range_ptr();
     
            m_Ptr = ptr;
            return *this;
        }
     
        /** Operateur += et -=  **/
        template<typename Type>
        smart_ptr<Type> &smart_ptr<Type>::operator-=(s32 i){
            testPointer();
     
            Type *ptr = m_Ptr - i;
     
            /** Le pointeur à le droit de pointé sur m_Begin **/
            if(ptr < m_Begin || ptr > m_End)
                throw out_of_range_ptr();
     
            m_Ptr = ptr;
            return *this;
        }
     
        /** Opérateur d'incrémentation préFixé **/
        template<typename Type>
        smart_ptr<Type> &smart_ptr<Type>::operator++(void){
            return *this += 1;
        }
     
        template<typename Type>
        smart_ptr<Type> &smart_ptr<Type>::operator--(void){
            return *this -= 1;
        }
     
        /** Opérateur d'incrémentation postFixé **/
        template<typename Type>
        smart_ptr<Type> smart_ptr<Type>::operator++(sint){
            smart_ptr<Type> ptr(*this);
     
            ++*this;
     
            return ptr;
        }
     
        template<typename Type>
        smart_ptr<Type> smart_ptr<Type>::operator--(sint){
            smart_ptr<Type> ptr(*this);
     
            --*this;
     
            return ptr;
        }
     
        /** opérateur + et - de type : ptr + x **/
        template<typename Type>
        smart_ptr<Type> operator+(smart_ptr<Type> const &ptr1, s32 i){
            smart_ptr<Type> ptr(ptr1);
     
            ptr += i;
     
            return ptr;
        }
     
        template<typename Type>
        smart_ptr<Type> operator-(smart_ptr<Type> const &ptr1, s32 i){
            smart_ptr<Type> ptr(ptr1);
     
            ptr -= i;
     
            return ptr;
        }
     
        /** Opérateur + et - de type : x + ptr **/
        template<typename Type>
        smart_ptr<Type> operator+(s32 i, smart_ptr<Type> const &ptr1){
            return smart_ptr<Type>(ptr1 + i);
        }
     
        template<typename Type>
        smart_ptr<Type> operator-(s32 i, smart_ptr<Type> const &ptr1){
            return smart_ptr<Type>(ptr1 - i);
        }
     
        /** Destructeur **/
        template<typename Type>
        smart_ptr<Type>::~smart_ptr(void){
            subPtr(); // On enlève une référence
        }
    }
     
    #endif // QGM_PTR_H_INCLUDED
    Merci de vos conseils

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Bonjour,

    J'ai pas lu dans les détails, mais quelques remarques :


    1. L'évolution de std::auto_ptr (déprécié à l'heure actuelle) existe déjà et se nomme std::unique_ptr.
    2. L'équivalent de ce que tu as codé existe aussi et se nomme std::shared_ptr.
    3. La responsabilité des classes de pointeur intelligent c'est de s'occuper de la libération des ressources selon une politque déterminée. Ainsi ton constructeur explicite n'a, AMA, pas trop sa place ici.
    4. Pour ton opérateur d'affectation : idiom copy-and-swap.
    5. Tu as un réel intérêt à utiliser une std::map<void*,u32> à la place d'un u32* en guise de compteur dans les instances ? (u32* ou plus évolué, peu importe) (*)
    6. Les opérateurs d'arithmétiques sur les pointeurs intelligent me gènent un peu. Il est vrai que les pointeurs intelligent doivent avoir une sémantique de pointeur. Sauf que cette arithmétique casse quand même un peu la notion de ressource, on ne lui dit plus "occupes toi de ca pour moi" mais "occupe toi de cet endroit". Et tu oublies de mettre à jour tes conteurs dans ces opérations d'ailleurs.
    7. L'idée de gérer en même temps les tableaux et les pointeurs simples ne me gène pas, cependant trouver dans l'interface de la classe une opération qui n'a potentiellement aucun sens (operator[]) me gène un peu plus. Je vois deux approches :
      • Tu considères que la ressource gérée est le tableau dans son ensemble, et dans ce cas il n'y a pas de raison de fournir d'opérateur [] : il s'occupe juste de gérer le tableau, pas d'y accéder.
      • Tu considères qu'il gère un ensemble d'éléments consécutifs, et dans ce cas tu peux le faire en créant une spécialisation (pour T[]), pour gérer ce cas.
    8. Toujours sur les tableaux et pour le premiers cas, on peut aller plus loin. En effet tu réalises une classe gérant une ressource, qu'est ce qui change entre les deux types de ressources ? La facon de la détruire : delte, delete []. On pourrait d'ailleurs imaginer des ressources qui ont un processus de destruction qui peut être plus complexe qu'un simple delete. L'idée pourrait être alors d'ajouter un paramètre optionnel à ton constructeur et/ou ta liste de paramètre template (je te laisse réflechir à la différence que ca introduit et aux éventuelles utilités), qui permettrait de faire cette libération de la ressource. Ainsi au final ta classe s'occuperais principement de savoir quand libérer les ressource, et laisserais cette tâche à ce nouveaux paramètre qui serait alors la politique de destruction.
    9. Ton style de programmation est très défensif je trouve. Les divers vérifications que tu fais devraient plutôt être des assertions à mon avis. Dans le sens où si elles échouent alors c'est une erreur du programmeur.
    10. Je n'ai pas fait attention, mais si tu veux rendre ta classe utilisable en MT, il faut faire attention, entre autre le compteur doit être atomique.
    11. Si tu veux aller plus loin, il y a un chapitre qui traite des pointeurs intelligents dans MC++D, et la lecture du code des pointeurs intelligent de boost (au moins l'interface) et de l'interface proposé dans la bibliothèque standard peut se révéler instructif. (D'ailleurs l'ensmble de mon message s'inspirer de ces 3 ressources)


    (*) Je vois bien un intérêt réel, cependant les implémentations actuelles des pointeurs intelligent considèrent que l'utilisateur demande explicitement la gestion de la ressource lorsqu'il construit le pointeur intelligent. Et qu'ainsi si il construit deux fois le pointeur intelligent depuis la même ressource c'est qu'il demande explictement de la gérer deux fois, par contre tant qu'il manipule le pointeur intelligent (copie/affectation) alors elle est bien gérée comme une seule et même ressource.

  3. #3
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut

    Pour rappel, JolyLoic avait écrit un tutoriel sur les pointeurs intelligents et présentait une approche pour créer sa propre classe de pointeur : http://loic-joly.developpez.com/tuto...mart-pointers/
    A lire

  4. #4
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    <HS>
    Il ne faudrait pas faire un MaJ ou une note de bas de page concernant la partie de cet article utilisant les concepts qui auraient du être dans le C++11 et qui n'y sont finalement pas ?
    </HS>

  5. #5
    Membre confirmé
    Inscrit en
    Mars 2006
    Messages
    209
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 209
    Par défaut
    Salut, déjà merci de vos réponses .

    1) Pour unique ptr, je pense qu'il possède le même problème que auto_ptr (les copies etc ^^ ).

    2) Ha, je pensais qu'il n'étais pas encore standard (pour ça que je code ça)^^.

    3) Pour moi, je trouve ça plus facile, mais tu as raison cependant .

    4) J'incrémente la référence donc c'est bon non?

    5) C'était plus facile à gérer pour moi ^^ Ton explication est plutôt compliqué pour moi ^^.

    6) Le compteur est apparemment bien gérer, je n'ai pas eu de problème avec les recopies ni incrémentations etc pourtant...

    7) Les spécialisations, je n'en suis pas encore, sinon oui, j'essayais de reproduire le plus fidèlement possible les pointeurs.

    8) Effectivement, c'est une très bonne idée, ça m'aurait enlever pas mal de problème de conception .

    9) Effectivement, je n'y avais pas penser...

    10) MT et atomique? Je n'ai pas compris...

    11) je ne connais pas MC++D. Pour Boost, d'après ce que j'ai compris, si Linus Torvald à la haine contre le C++, c'est surtout pour des raisons de portabilité à cause de Boost. Sinon, ben, faut voir comment je peux regarder comment est coder et l'interface et le code des pointeurs.

    Moralité : Etant donné que les shared_ptr sont standard, je vais utiliser ceux là .

    Pour le tuto, ben je lirais ça plus tard ^^.

  6. #6
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    2) c'est standard dans la nouvelle norme (et avant cela, c'était dans la norme TR1) et implémenté dans certains compilateur depuis des années (gcc)

    10) MT = multithread ; atomique = opération qui ne peut être intérompu avant la fin de son déroulement (wiki)

    11) non, parce que c'est un crétin fermé sur son monde

Discussions similaires

  1. Demande d'avis sur un bouquin (Deitel)
    Par oodini dans le forum C++
    Réponses: 7
    Dernier message: 26/02/2005, 01h50
  2. Votre avis sur des morceaux de resumes
    Par Asarnil dans le forum C++
    Réponses: 5
    Dernier message: 03/01/2005, 15h22

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