Namespaces
Variants

std::shared_ptr<T>:: reset

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)
void reset ( ) noexcept ;
(1) (depuis C++11)
template < class Y >
void reset ( Y * ptr ) ;
(2) (depuis C++11)
template < class Y, class Deleter >
void reset ( Y * ptr, Deleter d ) ;
(3) (depuis C++11)
template < class Y, class Deleter, class Alloc >
void reset ( Y * ptr, Deleter d, Alloc alloc ) ;
(4) (depuis C++11)

Remplace l'objet géré par un objet pointé par ptr . Un déstructeur optionnel d peut être fourni, qui sera utilisé ultérieurement pour détruire le nouvel objet lorsqu'aucun shared_ptr ne le possède. Par défaut, l'expression delete est utilisée comme déstructeur. L'expression delete appropriée correspondant au type fourni est toujours sélectionnée, ce qui explique pourquoi la fonction est implémentée comme template utilisant un paramètre séparé Y .

Si * this possède déjà un objet et qu'il est le dernier shared_ptr le possédant, l'objet est détruit via le suppresseur possédé.

Si l'objet pointé par ptr est déjà détenu, la fonction entraîne généralement un comportement indéfini.

1) Libère la propriété de l'objet géré, s'il y en a un. Après l'appel, * this ne gère aucun objet. Équivalent à shared_ptr ( ) . swap ( * this ) ; .
2-4) Remplace l'objet géré par un objet pointé par ptr . Y doit être un type complet et implicitement convertible en T . De plus :
2) Utilise l'expression delete comme suppresseur. Une expression delete valide doit être disponible, c'est-à-dire que delete ptr doit être bien formée, avoir un comportement bien défini et ne lever aucune exception. Équivalent à shared_ptr < T > ( ptr ) . swap ( * this ) ; .
3) Utilise le déléteur spécifié d comme déléteur. Deleter doit être invocable pour le type T , c'est-à-dire que d ( ptr ) doit être bien formé, avoir un comportement bien défini et ne lever aucune exception. Deleter doit être CopyConstructible , et son constructeur de copie et son destructeur ne doivent pas lever d'exceptions. Équivalent à shared_ptr < T > ( ptr, d ) . swap ( * this ) ; .
4) Identique à (3) , mais utilise en plus une copie de alloc pour l'allocation des données à usage interne. Alloc doit être un Allocator . Le constructeur par copie et le destructeur ne doivent pas lever d'exceptions. Équivalent à shared_ptr < T > ( ptr, d, alloc ) . swap ( * this ) ; .

Table des matières

Paramètres

ptr - pointeur vers un objet dont il faut acquérir la propriété
d - suppresseur à stocker pour la suppression de l'objet
alloc - allocateur à utiliser pour les allocations internes

Valeur de retour

(aucun)

Exceptions

2) 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. delete ptr est appelé si une exception se produit.
3,4) 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.

Exemple

#include <iostream>
#include <memory>
struct Foo
{
    Foo(int n = 0) noexcept : bar(n)
    {
        std::cout << "Foo::Foo(), bar = " << bar << " @ " << this << '\n';
    }
    ~Foo()
    {
        std::cout << "Foo::~Foo(), bar = " << bar << " @ " << this << '\n';
    }
    int getBar() const noexcept { return bar; }
private:
    int bar;
};
int main()
{
    std::cout << "1) propriété exclusive\n";
    {
        std::shared_ptr<Foo> sptr = std::make_shared<Foo>(100);
        std::cout << "Foo::bar = " << sptr->getBar() << ", use_count() = "
                  << sptr.use_count() << '\n';
        // Réinitialiser le shared_ptr sans lui fournir une nouvelle instance de Foo.
        // L'ancienne instance sera détruite après cet appel.
        std::cout << "appeler sptr.reset()...\n";
        sptr.reset(); // appelle le destructeur de Foo ici
        std::cout << "Après reset() : use_count() = " << sptr.use_count()
                  << ", sptr = " << sptr << '\n';
    }   // Aucun appel au destructeur de Foo, il a été effectué plus tôt dans reset().
    std::cout << "\n2) propriété exclusive\n";
    {
        std::shared_ptr<Foo> sptr = std::make_shared<Foo>(200);
        std::cout << "Foo::bar = " << sptr->getBar() << ", use_count() = "
                  << sptr.use_count() << '\n';
        // Réinitialise le shared_ptr, lui attribue une nouvelle instance de Foo.
        // L'ancienne instance sera détruite après cet appel.
        std::cout << "appeler sptr.reset()...\n";
        sptr.reset(new Foo{222});
        std::cout << "Après reset() : use_count() = " << sptr.use_count()
                  << ", sptr = " << sptr << "\nSortie de la portée...\n";
    }   // Appelle le destructeur de Foo.
    std::cout << "\n3) propriété multiple\n";
    {
        std::shared_ptr<Foo> sptr1 = std::make_shared<Foo>(300);
        std::shared_ptr<Foo> sptr2 = sptr1;
        std::shared_ptr<Foo> sptr3 = sptr2;
        std::cout << "Foo::bar = " << sptr1->getBar() << ", use_count() = "
                  << sptr1.use_count() << '\n';
        // Réinitialiser le shared_ptr sptr1, lui attribuer une nouvelle instance de Foo.
        // L'ancienne instance restera partagée entre sptr2 et sptr3.
        std::cout << "appeler sptr1.reset()...\n";
        sptr1.reset(new Foo{333});
        std::cout << "Après reset():\n"
                  << "sptr1.use_count() = " << sptr1.use_count()
                  << ", sptr1 @ " << sptr1 << '\n'
                  << "sptr2.use_count() = " << sptr2.use_count()
                  << ", sptr2 @ " << sptr2 << '\n'
                  << "sptr3.use_count() = " << sptr3.use_count()
                  << ", sptr3 @ " << sptr3 << '\n'
                  << "Sortie de la portée...\n";
    }   // Appelle deux destructeurs de: 1) Foo détenu par sptr1,
        // 2) Foo partagé entre sptr2/sptr3.
}

Sortie possible :

1) propriété unique
Foo::Foo(), bar = 100 @ 0x23c5040
Foo::bar = 100, use_count() = 1
appel de sptr.reset()...
Foo::~Foo(), bar = 100 @ 0x23c5040
Après reset(): use_count() = 0, sptr = 0
2) propriété unique
Foo::Foo(), bar = 200 @ 0x23c5040
Foo::bar = 200, use_count() = 1
appel de sptr.reset()...
Foo::Foo(), bar = 222 @ 0x23c5050
Foo::~Foo(), bar = 200 @ 0x23c5040
Après reset(): use_count() = 1, sptr = 0x23c5050
Sortie de la portée...
Foo::~Foo(), bar = 222 @ 0x23c5050
3) propriété multiple
Foo::Foo(), bar = 300 @ 0x23c5080
Foo::bar = 300, use_count() = 3
appel de sptr1.reset()...
Foo::Foo(), bar = 333 @ 0x23c5050
Après reset():
sptr1.use_count() = 1, sptr1 @ 0x23c5050
sptr2.use_count() = 2, sptr2 @ 0x23c5080
sptr3.use_count() = 2, sptr3 @ 0x23c5080
Sortie de la portée...
Foo::~Foo(), bar = 300 @ 0x23c5080
Foo::~Foo(), bar = 333 @ 0x23c5050

Voir aussi

construit un nouveau shared_ptr
(fonction membre publique)