2011-01-30 3 views
2

Je voulais juste avoir une nouvelle paire d'yeux que le code ci-dessous est correct en ce que:boost :: sémantique shared_ptr (copie)

Les pointeurs contenus dans le trifoo d'objet (stocké dans un ptr_vector) sont Partagée pointeurs f, g, h.

Aussi, quel est le résultat de la copie shared_ptr dans le constructeur de trifoo; est-ce la méthode correcte de 'partage' shared_ptr, en veillant à ce que le nombre de références soit augmenté etc. Tous mes autres doutes ont pu être vérifiés, mais je ne suis pas sûr de pouvoir vérifier cela (correctement). Toute critique est la bienvenue aussi.

#include <boost/ptr_container/ptr_vector.hpp> 
#include <boost/shared_ptr.hpp> 

class foo { 
    int a, b; 
public: 
    foo(int A, int B) : a(A), b(B) {} 
}; 

typedef boost::shared_ptr<foo> foo_ptr; 

class trifoo { 
    foo_ptr c, d, e; 
public: 
    trifoo(const foo_ptr& C, const foo_ptr& D, const foo_ptr& E) : c(C), d(D), e(E) {} 
}; 

int main() { 
    for (int i = 0; i < 5000000; i++) { 
     foo_ptr f(new foo(1,2)); 
     foo_ptr g(new foo(2,3)); 
     foo_ptr h(new foo(4,5)); 

     boost::ptr_vector<trifoo> tris; 

     tris.push_back(new trifoo(f, g, h)); 
    } 

    return 0; 
} 

Remarque: la boucle inutile consistait à tester les fuites de mémoire, dont aucune ne s'est produite.

+1

semble bien pour moi. Cependant, vous devriez préférer une liste d'initialisation à assignation, et votre vecteur 'tris' n'aura jamais qu'un seul élément, vous vouliez probablement que cela soit hors de la boucle. – GManNickG

+0

C'était simplement pour tester les capacités d'un ptr_vector, cette implémentation n'est pas pour une application pratique - et merci. – dcousens

Répondre

6

Le code semble être techniquement correct.

La sémantique de la copie d'un shared_ptr, cependant, est que le nombre de références de l'objet référencé est augmenté. Cela fonctionne juste. Pas d'inquiétudes à avoir.

Certaines questions de style, cependant:

  • Passing shared_ptr par référence ou déclarant const, n'a pas de sens. C'est parce qu'il peut toujours être copié. Il suffit de passer ces shared_ptr par valeur.

  • Utilisez les listes d'initialisation de constructeur à la place des affectations lorsque cela est pratiquement possible. Avoir les trois new dans les expressions différentes est très bon. Cela évite un écueil de sécurité exceptionnel. Mais encore mieux, mettez cette logique de création dans une fonction d'usine.

Vive & HTH.,

+0

Merci pour la réponse, en ce qui concerne la fonction d'usine, ayant juste appris sur ce concept, cela signifierait (approximativement) avoir une fonction telle que: foo_ptr foo :: makeFooPtr (int un, int b) {return foo_ptr (nouveau foo (a, b)); } Ou au moins le long de ces lignes. – dcousens

+0

Ne le ferait pas par référence enregistrer une copie (si une copie est faite)? Je les prendrais en valeur, puis les échangerais en mes membres, en C++ 03. – GManNickG

+0

C'était mon plus grand doute, je n'étais pas sûr de savoir comment le shared_ptr analyserait, la sémantique sur ce qui est réellement copié n'était pas claire pour moi. Je ne peux qu'imaginer que le compteur de référence reste cohérent, il doit pointer vers le même pointeur indépendamment de la copie? Aussi, comment pourrais-je mettre en place un échange comme mentionné. – dcousens

Questions connexes