IL est dit un peu partout que les ptr les plus utilisés sont ceux du type shared_ptr, hors je ne vois pas trop l'intérêt d'avoir un mécanisme de partage de ptr, bien souvent on a un ptr et il y a un 'seul' propriétaire, je me trompe ?
Version imprimable
IL est dit un peu partout que les ptr les plus utilisés sont ceux du type shared_ptr, hors je ne vois pas trop l'intérêt d'avoir un mécanisme de partage de ptr, bien souvent on a un ptr et il y a un 'seul' propriétaire, je me trompe ?
Bonjour,
C'est exact. Si un scoped_ptr suffit, il est préférable de l'utiliser a la place du shared_ptr. (Et fortement préférable a l'auto_ptr)
PS: Sauf si c'est pour faire une "implémentation privé", car la seul le shared_ptr le permettra. (l'auto_ptr aussi, mais la c'est le drame garantie)
en faite les cas d'utilisations des shared m'ont l'air très restreint
Pas tant que ca. Une utilisation très courante, c'est pour faire un conteneur de shared_ptr. Style vector<shared_ptr<MaClass> >. En effet, le vector requiert un objet copyable. Le scoped_ptr ne l'est pas.
Autre exemple, on as un cache d'images(par exemple) en mémoire. Chaque images ne doit pas être supprimée tant qu'elle est utilisée au moins a un endroit dans le programme. C'est un cas typique de propriété partagé, et c'est très courant.
c'est là où c'est un peu space car dans un code comme celui ci où est la notion de partage, au retour de add seul sp est propriétaire du pointeur, hors là on est obliger d'utiliser du sharedCode:
1
2
3
4
5
6
7
8
9
10 boost::scoped_ptr<int> add( ) { return boost::scoped_ptr<int>(new int(1)); } int main() { boost::scoped_ptr<int> sp = add(); getchar(); }
EDIT: il faut peut être plutôt utiliser un auto_ptr alors
Ton code compilera pas. Parce que justement le scoped_ptr est pas fait pour ça. (c'est juste une enveloppe RAII-sante)
Pour ça que quand tu dis que c'est le plus utile, je te dis que non, car en général quand j'ai a utiliser un pointeur c'est justement que je veux pouvoir étendre ça durée de vie et le passer de "main en main"
je sais que ça compile pas,c'était pour l'exemple
Mais dans ce cas là un un auto_ptr est peut être le bon outil ?
Code:
1
2
3
4
5
6
7
8
9
10
11
12 std::auto_ptr<int> add( ) { return std::auto_ptr<int>(new int(1)); } int main() { std::auto_ptr<int> sp = add(); std::cout << *sp; getchar(); }
C'est en effet dans ce cas uniquement que l'auto_ptr est utile. Mais le shared_ptr est quand même plus safe.
effectivement ça évite ce genre de situation, mais l'auto_ptr conserve donc une propriété intéressante suivant le cas que les autres smart ptr n'ont pasCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 std::auto_ptr<int> add( ) { return std::auto_ptr<int>(new int(1)); } void add(std::auto_ptr<int> f ) { } int main() { std::auto_ptr<int> sp = add(); add(sp); std::cout << *sp; getchar(); }
Oui. En attendant le C++1x et son unique_ptr.
D'ailleurs une petite question concernant l'implémetation d'auto ptr :
A quoi sert le dernier constructeur ?Code:
1
2
3
4
5
6
7
8
9 template <class X> class auto_ptr { public: typedef X element_type; // 20.4.5.1 construct/copy/destroy: explicit auto_ptr(X* p =0) throw(); auto_ptr(auto_ptr&) throw(); template <class Y> auto_ptr(auto_ptr<Y>&) throw();
Conversion. (si elle existe entre X et Y)
ça s'utilise comment , le code suivant ne passe pas :
Code:
1
2
3 std::auto_ptr<short> p; std::auto_ptr<int> m(p);
Changer quoi ? Ton objectif... short* et int* ne sont pas compatible, il n'y a pas de raison qu'un xxx_ptr<short> ou un xxx_ptr<int> le soient...
Un exemple qui marche (aux erreurs de frappe près) :
Code:
1
2
3
4
5 class A{}; class B : public A {}; auto_ptr<B> ptrB(new B); auto_ptr<A> ptrA(ptrB);
Salut.
Y as t'il une réelle différence entre scoped_ptr et auto_ptr?
Si j'ai bien compris scoped_ptr n'est pas copiable alors que auto_ptr oui(mais c'est un transfert de pointeur et non une copie)
ok oui je pensais qu'une conversion implicite pouvait passer entre short et int. Si on définit deux classes X et Y avec un operateur de transtypage entre les deux types ça peut passer ? ( j'ai essayé mais sans succes , peut-être une erreur de syntaxe...), je pose ça par curiosité j'ai conscience que je n'aurais jamais à utiliser ça :D
Pour répondre à la question initiale, je trouve que shared_ptr est très adapté dans la plupart des cas. Il a un comportement attendu et très sain, il n'y a pas de pièges.
scoped_ptr n'est pas copiable, auto_ptr transfère la responsabilité. Il fait faire attention avec ces bêtes là ! ;)
Personnellement, je n'utilise que shared_ptr (parfois en combinaison avec weak_ptr), même si une implémentation par comptage de référence n'est pas ce que j'attend dans 100% des cas. En cas d'évolution de cahier des charges, il se peut qu'on doive partager une ressource.
Au passage, les pointeurs sous Python fonctionne avec un compteur (comme shared_ptr), c'est vraiment une solution "passe-partout" pour un surcout minime.