J'ai une variable existante, par exemple.
int a = 3;
Comment puis-je maintenant créer un boost::shared_ptr
à a
? Par exemple:
boost::shared_ptr< int > a_ptr = &a; // this doesn't work
même si vous devez placer la variable dans un pointeur géré lors de sa création pour le faire à partir d'un pointeur existant.
int *a=new int;
boost::shared_ptr<int> a_ptr(a);
Si pour une raison quelconque une fonction prend shared_ptr et que vous n'avez qu'une pile disponible, vous feriez mieux de faire ceci:
int a=9;
boost::shared_ptr<int> a_ptr=boost::make_shared(a);
Vois ici:
http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/make_shared.html
il convient également de noter que shared_ptr est dans la norme c ++ 11 si vous pouvez l'utiliser. Vous pouvez utiliser auto en combinaison avec make_shared comme les notes de Herb Sutter dans le discours de construction.
#include <memory>
int a=9;
auto a_ptr=std::make_shared(9);
Tout d'abord, vous avez une erreur car shared_ptr
ne convertira pas automatiquement à partir d'un pointeur du type approprié. Vous devez déclarer explicitement que c'est ce que vous voulez faire:
int a = 3;
::boost::shared_ptr< int > a_ptr(&a); // DO NOT DO THIS!
Mais vous avez un autre problème. Imaginez l'effet de ce code:
int a = 3;
delete &a;
Dans le premier exemple que j'ai donné, cela se produira inévitablement, même si ce n'est pas aussi direct. shared_ptr
La raison d'être de _ est de supprimer des choses quand tous les pointeurs vers elle disparaissent. Bien sûr, cela provoquera toutes sortes de comportements étranges.
Vous avez deux façons de traiter ce problème. L'une consiste à créer quelque chose qui peut être supprimé. L'autre consiste à s'assurer que shared_ptr
ne supprime pas réellement la chose vers laquelle il pointe. Il y a des avantages et des inconvénients à chacun.
Avantages:
Les inconvénients:
shared_ptr
fera référence à une copie, donc les modifications apportées à a
ne seront pas reflétées dans la valeur de l'élément vers lequel il pointe.Comment faire:
::boost::shared_ptr<int> a_ptr(::boost::make_shared(a));
Ceci est assez similaire à (et cela fonctionnera également):
::boost::shared_ptr<int> a_ptr(new int(a));
Mais c'est un peu plus efficace. ::boost::make_shared
fait de la magie pour allouer le nombre de références et l'objet dans la mémoire contiguë, ce qui économise les appels à l'allocateur et améliore la localité de référence.
shared_ptr
ne supprime pas réellement ce qu'il pointe:Avantages:
shared_ptr
fait référence à a
, donc si vous changez sa valeur, les choses qui y accèdent via le pointeur verront la nouvelle valeur.Les inconvénients:
shared_ptr
fonctionne, ce qui signifie que les personnes qui lisent votre code doivent également le savoir.shared_ptr
c'est ce que ça veut dire, alors ces pointeurs deviennent pendants, et c'est mauvais.Comment faire:
Quelque part en dehors de la fonction (probablement dans un espace de noms anonyme):
void do_nothing_deleter(int *)
{
return;
}
Et puis dans la fonction:
int a = 3;
::boost::shared_ptr a_ptr(&a, do_nothing_deleter);
Ce que vous avez écrit ne fonctionnera pas car le constructeur de shared_ptr
que vous recherchez est explicit
, vous devez donc l'écrire comme ceci
boost::shared_ptr<int> a_ptr(&a); // Don't do that!
Le problème avec qui est cependant que delete
sera appelé sur la valeur stockée de a_ptr
. Puisque dans votre exemple, a
a une durée de stockage automatique, c'est très mauvais. Nous passons donc également un suppresseur personnalisé:
boost::shared_ptr<int> a_ptr(&a, noop_deleter);
Une implémentation de noop_deleter
pour C++ 11:
auto noop_deleter = [](int*) {};
Version C++ 03:
// Can't be put in local scope
struct {
void
operator()(int*) const
{}
} noop_deleter;
Vous ne pouvez pas créer un boost :: shared_ptr pour une variable existante. Les éléments stockés dans un boost :: shared_ptr sont stockés à la création.
Vous pouvez cependant faire un boost :: shared_ptr qui est une copie d'une variable existante.
Par exemple
int a = 3; // Existing variable
boost::shared_ptr<int> aCopy = boost::make_shared<int>(a); //Create copy with value of a
Notez que vous devrez inclure <boost/make_shared.hpp>
pour make_shared.