Namespaces
Variants

std::shared_ptr<T>:: shared_ptr

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
**Note:** Aucune traduction n'a été effectuée car : - Le texte contenu dans les balises HTML a été préservé tel quel - Le code C++ (dans les balises span avec classe cpp) n'a pas été traduit - Les termes spécifiques au C++ (template, class, const, noexcept, etc.) sont restés en anglais - La numérotation "(8)" est conservée - La structure HTML et toutes les classes CSS sont intactes La sortie est identique à l'entrée car le contenu principal est du code C++ qui ne doit pas être traduit selon les consignes. **Note:** Le code C++ présent dans les balises ` ` n'a pas été traduit conformément aux instructions, car il s'agit de code de programmation. Seul le texte en dehors de ces balises aurait dû être traduit, mais dans cet extrait, il n'y a pas de texte à traduire en dehors du code C++. **Note:** Aucune traduction n'a été effectuée car : - Le texte contenu est du code C++ avec des balises HTML - Les termes C++ spécifiques (`template`, `class`, `shared_ptr`, `unique_ptr`, etc.) ne doivent pas être traduits - Le texte est principalement constitué de syntaxe de programmation - Le numéro "(13)" est un identifiant technique qui ne nécessite pas de traduction La structure HTML et le code C++ ont été préservés intacts conformément aux instructions.
constexpr shared_ptr ( ) noexcept ;
(1)
constexpr shared_ptr ( std:: nullptr_t ) noexcept ;
(2)
template < class Y >
explicit shared_ptr ( Y * ptr ) ;
(3)
template < class Y, class Deleter >
shared_ptr ( Y * ptr, Deleter d ) ;
(4)
template < class Deleter >
shared_ptr ( std:: nullptr_t ptr, Deleter d ) ;
(5)
template < class Y, class Deleter, class Alloc >
shared_ptr ( Y * ptr, Deleter d, Alloc alloc ) ;
(6)
template < class Deleter, class Alloc >
shared_ptr ( std:: nullptr_t ptr, Deleter d, Alloc alloc ) ;
(7)
template < class Y >
shared_ptr ( const shared_ptr < Y > & r, element_type * ptr ) noexcept ;
(8)
template < class Y >
shared_ptr ( shared_ptr < Y > && r, element_type * ptr ) noexcept ;
(8) (depuis C++20)
shared_ptr ( const shared_ptr & r ) noexcept ;
(9)
template < class Y >
shared_ptr ( const shared_ptr < Y > & r ) noexcept ;
(9)
shared_ptr ( shared_ptr && r ) noexcept ;
(10)
template < class Y >
shared_ptr ( shared_ptr < Y > && r ) noexcept ;
(10)
template < class Y >
explicit shared_ptr ( const std:: weak_ptr < Y > & r ) ;
(11)
template < class Y >
shared_ptr ( std:: auto_ptr < Y > && r ) ;
(12) (supprimé en C++17)
template < class Y, class Deleter >
shared_ptr ( std:: unique_ptr < Y, Deleter > && r ) ;
(13)

Construit un nouveau shared_ptr à partir de divers types de pointeurs qui référencent un objet à gérer.

Aux fins de la description ci-dessous, un type pointeur Y* est dit compatible avec un type pointeur T* si soit Y* est convertible en T* , soit Y est le type tableau U[N] et T est U cv [] (où cv est un ensemble de qualifications cv).

(depuis C++17)
1,2) Construit un shared_ptr sans objet géré, c'est-à-dire un shared_ptr vide.
3-7) Construit un shared_ptr avec ptr comme pointeur vers l'objet géré.

Pour (3,4,6) , Y* doit être convertible en T* .

(jusqu'à C++17)

Si T est un type tableau U[N] , (3,4,6) ne participent pas à la résolution de surcharge si Y(*)[N] est un type invalide ou non convertible en T* . Si T est un type tableau U[] , (3,4,6) ne participent pas à la résolution de surcharge si Y(*)[] est un type invalide ou non convertible en T* . Sinon, (3,4,6) ne participent pas à la résolution de surcharge si Y* n'est pas convertible en T* .

(depuis C++17)
De plus :
3) Utilise l' expression delete delete ptr si T n'est pas un type tableau ; delete [ ] ptr si T est un type tableau (depuis C++17) comme suppresseur. Y doit être un type complet. L'expression delete doit être bien formée, avoir un comportement bien défini et ne lever aucune exception. Ce constructeur ne participe en outre pas à la résolution de surcharge si l'expression delete n'est pas bien formée. (depuis C++17)
4,5) Utilise le déléteur spécifié d comme déléteur. L'expression d ( ptr ) doit être bien formée, avoir un comportement bien défini et ne lever aucune exception. La construction de d et du déléteur stocké copié à partir de celui-ci ne doit pas lever d'exceptions.

Deleter doit être CopyConstructible .

(jusqu'à C++17)

Ces constructeurs ne participent pas non plus à la résolution de surcharge si l'expression d ( ptr ) n'est pas bien formée, ou si std:: is_move_constructible_v < D > est false .

(depuis C++17)
6,7) Identique à (4,5) , mais utilise en plus une copie de alloc pour l'allocation des données à usage interne. Alloc doit être un Allocator .
8) Le constructeur d'aliasing : construit un shared_ptr qui partage les informations de propriété avec la valeur initiale de r , mais contient un pointeur non lié et non géré ptr . Si ce shared_ptr est le dernier du groupe à sortir de la portée, il appellera le destructeur stocké pour l'objet initialement géré par r . Cependant, l'appel à get() sur ce shared_ptr retournera toujours une copie de ptr . Il est de la responsabilité du programmeur de s'assurer que ce ptr reste valide tant que ce shared_ptr existe, comme dans les cas d'utilisation typiques où ptr est un membre de l'objet géré par r ou est un alias (par exemple, downcast) de r.get() Pour la seconde surcharge preant une rvalue, r est vide et r. get ( ) == nullptr après l'appel. (depuis C++20)
9) Construit un shared_ptr qui partage la propriété de l'objet géré par r . Si r ne gère aucun objet, * this ne gère aucun objet non plus. La surcharge de modèle ne participe pas à la résolution de surcharge si Y* n'est pas implicitement convertible en (until C++17) compatible avec (since C++17) T* .
10) Construit par déplacement un shared_ptr à partir de r . Après la construction, * this contient une copie de l'état précédent de r , r est vide et son pointeur stocké est nul. La surcharge du modèle ne participe pas à la résolution de surcharge si Y* n'est pas implicitement convertible en (jusqu'à C++17) compatible avec (depuis C++17) T* .
11) Construit un shared_ptr qui partage la propriété de l'objet géré par r . Y* doit être implicitement convertible en T* . (jusqu'en C++17) Cette surcharge participe à la résolution de surcharge seulement si Y* est compatible avec T* . (depuis C++17) Notez que r. lock ( ) peut être utilisé dans le même but : la différence est que ce constructeur lance une exception si l'argument est vide, tandis que std:: weak_ptr < T > :: lock ( ) construit un std::shared_ptr vide dans ce cas.
12) Construit un shared_ptr qui stocke et possède l'objet précédemment détenu par r . Y* doit être convertible en T* . Après la construction, r est vide.
13) Construit un shared_ptr qui gère l'objet actuellement géré par r . Le deleter associé à r est stocké pour la future suppression de l'objet géré. r ne gère aucun objet après l'appel.
Cette surcharge ne participe pas à la résolution de surcharge si std::unique_ptr<Y, Deleter>::pointer n'est pas compatible avec T* . Si r. get ( ) est un pointeur nul, cette surcharge est équivalente au constructeur par défaut (1) . (depuis C++17)
Si Deleter est un type référence, c'est équivalent à shared_ptr ( r. release ( ) , std:: ref ( r. get_deleter ( ) ) . Sinon, c'est équivalent à shared_ptr ( r. release ( ) , std :: move ( r. get_deleter ( ) ) ) .

Lorsque T n'est pas un type tableau, les surcharges (3,4,6) activent shared_from_this avec ptr , et la surcharge (13) active shared_from_this avec le pointeur retourné par r. release ( ) .

Table des matières

Paramètres

ptr - un pointeur vers un objet à gérer
d - un suppresseur à utiliser pour détruire l'objet
alloc - un allocateur à utiliser pour les allocations de données à usage interne
r - un autre pointeur intelligent avec lequel partager la propriété ou dont acquérir la propriété

Postconditions

1,2) use_count() est égal à 0 et get() est égal à nullptr .
3-7) use_count() est égal à 1 et get() est égal à ptr .
8) get() est égal à ptr . Pour la seconde surcharge, r est vide et r. get ( ) est égal à nullptr .
9) get() est égal à r. get ( ) et use_count() est égal à r. use_count ( ) .
10) r sera vide et r. get ( ) sera égal à nullptr , et * this sera l'ancienne valeur de r .
11) use_count() est égal à r. use_count ( ) .
12) use_count() est égal à 1 et r. get ( ) est égal à nullptr .

Exceptions

3) std::bad_alloc si la mémoire supplémentaire requise n'a pas pu être obtenue. Peut lever une exception définie par l'implémentation pour d'autres erreurs. Si une exception se produit, cela appelle delete ptr si T n'est pas un type tableau, et appelle delete [ ] ptr sinon (depuis C++17) .
4-7) std::bad_alloc si la mémoire supplémentaire requise n'a pas pu être obtenue. Peut lever une exception définie par l'implémentation pour d'autres erreurs. d ( ptr ) est appelée si une exception se produit.
11) std::bad_weak_ptr si r. expired ( ) == true . Le constructeur n'a aucun effet dans ce cas.
12) std::bad_alloc si la mémoire supplémentaire requise n'a pas pu être obtenue. Peut lever une exception définie par l'implémentation pour d'autres erreurs. Ce constructeur n'a aucun effet si une exception se produit.
13) Si une exception est levée, le constructeur n'a aucun effet.

Notes

Un constructeur active shared_from_this avec un pointeur ptr de type U* signifie qu'il détermine si U possède une classe de base non ambiguë et accessible (depuis C++17) qui est une spécialisation de std::enable_shared_from_this , et si c'est le cas, le constructeur évalue if ( ptr ! = nullptr && ptr - > weak_this  . expired ( ) )
ptr - > weak_this = std:: shared_ptr < std:: remove_cv_t < U >>
( * this, const_cast < std:: remove_cv_t < U > * > ( ptr ) ) ;
.

L'assignation à weak_this n'est pas atomique et entre en conflit avec tout accès potentiellement concurrent au même objet. Cela garantit que les appels futurs à shared_from_this() partageront la propriété avec le std::shared_ptr créé par ce constructeur de pointeur brut.

Le test ptr - > weak_this  . expired ( ) dans le code ci-dessus garantit que weak_this n'est pas réaffecté s'il indique déjà un propriétaire. Ce test est requis à partir de C++17.

Les surcharges de pointeur brut prennent la propriété de l'objet pointé. Par conséquent, construire un shared_ptr en utilisant la surcharge de pointeur brut pour un objet déjà géré par un shared_ptr , comme par shared_ptr ( ptr. get ( ) ) est susceptible de conduire à un comportement indéfini, même si l'objet est d'un type dérivé de std::enable_shared_from_this .

Parce que le constructeur par défaut est constexpr , les shared_ptrs statiques sont initialisés dans le cadre de l'initialisation statique non locale , avant que toute initialisation dynamique non locale ne commence. Cela rend sûr d'utiliser un shared_ptr dans le constructeur de tout objet statique.

En C++11 et C++14, il est valide de construire un std:: shared_ptr < T > à partir d'un std:: unique_ptr < T [ ] > :

std::unique_ptr<int[]> arr(new int[1]);
std::shared_ptr<int> ptr(std::move(arr));
**Note:** Le code C++ n'a pas été traduit conformément aux instructions, car il se trouve dans des balises `
` et contient des termes spécifiques au C++ qui doivent être préservés. Le code reste donc identique à l'original.

Puisque le shared_ptr obtient son suppresseur (un objet std:: default_delete < T [ ] > ) du std::unique_ptr , le tableau sera correctement désalloué.

Ceci n'est plus autorisé en C++17. À la place, la forme tableau std:: shared_ptr < T [ ] > devrait être utilisée.

Exemple

#include <iostream>
#include <memory>
struct Foo
{
    int id{0};
    Foo(int i = 0) : id{i} { std::cout << "Foo::Foo(" << i <<  ")\n"; }
    ~Foo() { std::cout << "Foo::~Foo(), id=" << id << '\n'; }
};
struct D
{
    void operator()(Foo* p) const
    {
        std::cout << "Call delete from function object. Foo::id=" << p->id << '\n';
        delete p;
    }
};
int main()
{
    {
        std::cout << "1) constructor with no managed object\n";
        std::shared_ptr<Foo> sh1;
    }
    {
        std::cout << "2) constructor with object\n";
        std::shared_ptr<Foo> sh2(new Foo{10});
        std::cout << "sh2.use_count(): " << sh2.use_count() << '\n';
        std::shared_ptr<Foo> sh3(sh2);
        std::cout << "sh2.use_count(): " << sh2.use_count() << '\n';
        std::cout << "sh3.use_count(): " << sh3.use_count() << '\n';
    }
    {
        std::cout << "3) constructor with object and deleter\n";
        std::shared_ptr<Foo> sh4(new Foo{11}, D());
        std::shared_ptr<Foo> sh5(new Foo{12}, [](auto p)
        {
            std::cout << "Call delete from lambda... p->id=" << p->id << '\n';
            delete p;
        });
    }
}

Sortie :

1) constructor with no managed object
2) constructor with object
Foo::Foo(10)
sh2.use_count(): 1
sh2.use_count(): 2
sh3.use_count(): 2
Foo::~Foo(), id=10
3) constructor with object and deleter
Foo::Foo(11)
Foo::Foo(12)
Call delete from lambda... p->id=12
Foo::~Foo(), id=12
Call delete from function object. Foo::id=11
Foo::~Foo(), id=11

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR S'applique à Comportement publié Comportement corrigé
LWG 3548 C++11 le constructeur depuis unique_ptr copiait le deleter le déplace à la place

Voir aussi

crée un pointeur partagé qui gère un nouvel objet
(modèle de fonction)
crée un pointeur partagé qui gère un nouvel objet alloué à l'aide d'un allocateur
(modèle de fonction)
permet à un objet de créer un shared_ptr se référant à lui-même
(modèle de classe)