Comment passer deleter à make_shared?
Depuis C++11, à cause de plusieurs raisons, les développeurs ont tendance à utiliser de pointeur intelligent classes pour la dynamique de durée de vie des objets. Et avec les nouvelles smart pointeur de classes, de normes, de même vous suggérons de ne pas utiliser des opérateurs comme new
lieu de cela, ils suggèrent d'utiliser make_shared
ou make_unique
afin d'éviter certaines erreurs.
Si vous voulez utiliser un pointeur intelligent de la classe, comme shared_ptr
, nous pouvons construire un, comme,
shared_ptr<int> p(new int(12));
Aussi nous aimerions passer une coutume deleter de pointeur intelligent classes,
shared_ptr<int> p(new int(12), deleter);
D'autre part, si nous aimons utiliser make_shared
d'allouer, pour ex. int
, au lieu d'utiliser new
et shared_ptr
constructeur, comme sur la première expression ci-dessus, nous pouvons utiliser
auto ip = make_shared<int>(12);
Mais ce qui si on aime également passer une coutume deleter à make_shared
, est-il une bonne façon de le faire? Semble que les compilateurs, au moins gcc, donne une erreur,
auto ip = make_shared<int>(12, deleter);
- Écrivez votre propre
make_shared()
qui prend en charge ce, c'est faisable.
Vous devez vous connecter pour publier un commentaire.
Comme d'autres l'ont dit,
make_shared
ne peut pas être utilisé avec un custom deleter. Mais je veux expliquer pourquoi.Personnalisé deleters existent parce que vous avez alloué le pointeur d'une manière spéciale, et, par conséquent, vous devez être en mesure de libérer en contrepartie d'une façon particulière. Eh bien,
make_shared
alloue le pointeur avecnew
. Les objets alloués avecnew
devrait être libéré avecdelete
. La norme deleter consciencieusement n'.En bref, si vous pouvez vivre avec l'allocation par défaut de comportement, vous pouvez vivre avec la valeur par défaut de libération de la mémoire comportement trop. Et si vous ne pouvez pas vivre avec l'allocation par défaut de comportement, vous devez utiliser
allocate_shared
, qui utilise la condition de l'allocateur à la fois à allouer et de libérer l'espace de stockage.Aussi,
make_shared
est permis (et presque certainement) d'allouer la mémoire pourT
et le bloc de contrôle pour les shared_ptr au sein de la même allocation. C'est quelque chose que votre deleter ne peut pas vraiment savoir parler ou de se traiter avec. Alors queallocate_shared
est capable de les gérer, depuis l'allocateur de vous fournir peut faire l'allocation et la désallocation de fonctions.shared_ptr
n'a pas nécessairement été "attribués" à tous. Vous pouvez utiliserfclose
pour fermer un FICHIER*, par exemple. À l'aide deallocate_shared
vous permet de contrôler l'allocation de mémoire, mais pas l'utilisation arbitraire des ressources. Vous avez encore de construire et de détruire un objet, non pas d'obtenir une "ressource" à partir d'une fonction et de les libérer avec un autre (deleter) de la fonction. Même si lwg 2070 est résolu que toujours ne permettent pas coutume deleters à faire/allocate_shared.shared_ptr
.X
, et les fonctionsget()
etput(X*)
. Vous pouvez l'utiliser avecshared_ptr<X>(get(), &put)
mais il n'y a pas moyen d'utilisermake_shared
ouallocate_shared
parce qu'ils dépendent l'un desizeof(X)
qui n'est pas connu.make_shared
ouallocate_shared
, puisque le but premier des deux est pour eux pour créer l'objet.allocate_shared
est inutile de faire diversion. Le point est que make_shared crée l'objet, de sorte que vous devez aussi faire confiance à "décréer" il.allocate_shared
est qu'il peut être utilisé dans de nombreux cas, où vous voulez une explicite deleter. Pas forcément tous, mais beaucoup.new
, il pourrait l'affecter, avecstd::allocator
(comme mon œuvre n'), oumalloc
. Ou un allocateur personnalisé, ou quelque chose d'autre. Vous ne savez pas, et si votre deleter ne sais pas quoi faire. make_shared crée l'objet, en quelque sorte, alors vous devez faire confiance à décréer il.Comme de la la documentation,
make_shared
accepte un liste des arguments avec lesquels une instance de T sera construit.En outre, la documentation dit que:
À cause de cela, vous pouvez en déduire que vous ne pouvez pas personnaliser la deleter.
Pour ce faire, vous devez créer la
shared_ptr
pour vous-même par le droit constructeur.Comme exemple d'un constructeur à partir de la liste proposée, vous pouvez utiliser:
Ainsi, le code sera quelque chose comme:
Au lieu de:
Vous ne pouvez pas.
make_shared<T>
transmet les arguments fournis par le constructeur de typeT
. Il est utilisé pour le cas simple où vous souhaitez que la valeur par défaut deleter.Il n'est pas précisé comment
make_shared
obtient la mémoire de l'objet (il pourrait utiliseroperator new
oumalloc
ou une sorte de allocateur) il n'est donc pas une coutume deleter pourrait savoir comment faire la bonne chose.make_shared
crée l'objet, de sorte que vous devez aussi compter sur elle pour détruire l'objet correctement et faire le nettoyage requis, quelle qu'elle soit.Je ne pense pas que c'est un très réalistes exemple. Une coutume deleter est généralement utilisé lorsque la ressource a été obtenue d'une manière spéciale. Si vous venez de créer avec
new
comme cela, alors pourquoi avez-vous besoin d'un custom deleter, de toute façon?Si vous voulez juste un peu de code à exécuter sur la destruction puis le mettre dans un destructeur! De cette façon, vous pouvez également l'utiliser avec
make_shared
par exempleCela vous donne un
shared_ptr<int>
qui est créé parmake_shared
(de sorte que vous obtenez la mémoire des optimisations effectuées parmake_shared
) qui va exécuter du code personnalisé sur la destruction.Si vous utilisez un personnalisé deleter vous ne pouvez pas utiliser
make_unique
oumake_shared
fonctions lorsque vous créez un pointeur intelligent objets . Depuis que nous avons besoin de fournir à notre clientèle des deleter ces fonctions ne supporte pas cela .Ne pas utiliser make_unique ou make_shared si vous avez besoin d'un custom deleter ou l'adoption d'un pointeur brut d'ailleurs.
L'idée est que si vous avez besoin d'un spécialisé façon de le supprimer de votre objet, vous avez probablement besoin spécialisés de façon à créer eux aussi .
Disons que nous avons une classe de Test
Mais si vous utilisez make_shared fonction, vous obtiendrez une erreur de compilation,
Fondamentalement make_shared fonction est un wrapper pour
new
etdelete
et si vous voulez une coutume deleter vous devez fournir vous possédeznew
etdelete