Outils pour utilisateurs

Outils du site


lang:cpp:smartptr

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
lang:cpp:smartptr [2019/11/07 23:29] – Ajout d'une source d'information rootlang:cpp:smartptr [2025/07/06 16:33] (Version actuelle) – [Préserver l'attribut const sur les pointeurs] : déplacement dans un article dédié root
Ligne 1: Ligne 1:
 {{ :lang:cpp:smartptr:cpp_smart_pointers_ebook.pdf |C++ smart pointers fluentcpp}} {{ :lang:cpp:smartptr:cpp_smart_pointers_ebook.pdf |C++ smart pointers fluentcpp}}
  
-====std::weak_ptr en tant que clé dans un conteneur==== +====Durée de vie====
-Il faut utiliser le comparateur ''owner_less''+
-<code cpp> +
-std::map<U, T, std::owner_less<U>> destination; +
-</code>+
  
-====Préserver l'attribut const sur les pointeurs==== +Lors d'un ''reset'', le nouvel objet commence par être construit avant de détruire le précédent. Si les objets ont une place importante en mémoire, il peut être intéressant de commencer par faire un ''reset()'' avant de faire le ''reset(...)''.
-Il faut utiliser ''propagate_const''.+
  
 +<code cpp>
 +#include <iostream>
 +#include <memory>
  
-Soit la classe commune ''X'' : +class A { 
- + public
-<code cpp> +  A() { std::cout << "Constructor\n"; } 
-struct X +  ~A() { std::cout << "Destructor\n"; }
-{ +
-  void g() const { std::cout << "g (const)\n"; } +
-  void g() { std::cout << "g (non-const)\n"; }+
 }; };
-</code> 
  
-et le programme commun : +int main() { 
- +  std::shared_ptr<A> a = std::make_shared<A>()
-<code cpp> +  a.reset(new A()); 
-int main() +  a = std::make_shared<A>();
-+
-  Y y+
-  y.f(); +
- +
-  const Y cy; +
-  cy.f();+
 } }
- 
 </code> </code>
  
-===Cas avec la classe ''X'' intégrée dans une classe ''Y''===+Sortie :
  
-<code cpp+<code> 
-struct Y +Constructor 
-{ +Constructor 
-  Y() { }+Destructor 
 +Constructor 
 +Destructor 
 +Destructor 
 +</code>
  
-  void f() const 
-  { 
-    std::cout << "f (const)\n"; 
-    m_ptrX.g(); 
-  } 
  
-  void f() +====Encapsuler fopen/close====
-  { +
-    std::cout << "f (non-const)\n"; +
-    m_ptrX.g(); +
-  }+
  
-  // IciX est une instance sans pointeur. +<code cpp> 
-  X m_ptrX; +std::unique_ptr<FILEdecltype(&fclose)> fp(std::fopen(filename.c_str(), "r"), &fclose);
-};+
 </code> </code>
  
-Rendu sans surprise :+[[https://stackoverflow.com/questions/26360916/using-custom-deleter-with-unique-ptr|using custom deleter with unique_ptr]] {{ :lang:cpp:smartptr:c_-_using_custom_deleter_with_unique_ptr_-_stack_overflow_28_12_2022_10_34_58_.html |Archive du 14/10/2014 le 28/12/2022}}
  
-<code> +====weak_ptr==== 
-f (non-const) + 
-g (non-const) +====std::weak_ptr en tant que clé dans un conteneur==== 
-f (const) +Il faut utiliser le comparateur ''owner_less''. 
-g (const)+<code cpp> 
 +std::map<U, T, std::owner_less<U>> destination;
 </code> </code>
  
-Si la méthode ''f const'' est appelée, la méthode ''g const'' est appelée également car une méthode ''const'' ne peut pas appeler une méthode non ''const''.+===Différencier empty et expired===
  
-===Cas avec un pointeur unique===+Sans passer par ''.lock()'' pour ''empty()''.
  
 <code cpp> <code cpp>
-struct Y +#include <iostream> 
-+#include <memory>
-  Y() : m_ptrX{} { }+
  
-  void f() const+class A {}; 
 + 
 +int main() {
   {   {
-    std::cout << "(const)\n"; +    std::weak_ptr<A> aa; 
-    m_ptrX->g();+ 
 +    if (!aa.owner_before(std::weak_ptr<A>{}) && !std::weak_ptr<A>{}.owner_before(aa)) { 
 +      std::cout << "empty1\n"; 
 +    
 +    if (aa.expired()) { 
 +      std::cout << "expired1\n"; 
 +    }
   }   }
  
-  void f() 
   {   {
-    std::cout << "(non-const)\n"; +    std::shared_ptr<A> a; 
-    m_ptrX->g();+    std::weak_ptr<A> aa = a; 
 + 
 +    if (!aa.owner_before(std::weak_ptr<A>{}&& !std::weak_ptr<A>{}.owner_before(aa)) { 
 +      std::cout << "empty2\n"; 
 +    
 +    if (aa.expired()) { 
 +      std::cout << "expired2\n" // False 
 +    }
   }   }
  
-  std::unique_ptr<Xm_ptrX+  
-}; +    std::weak_ptr<Aaa
-</code>+    { 
 +      std::shared_ptr<Aa = std::make_shared<A>(); 
 +      aa = a;
  
-Rendu : +      if (!aa.owner_before(std::weak_ptr<A>{}&& !std::weak_ptr<A>{}.owner_before(aa)) { 
- +        std::cout << "empty3\n";  // False 
-<code cpp> +      } 
-f (non-const) +      if (aa.expired()) { 
-(non-const) +        std::cout << "expired3\n";  // False 
-f (const) +      } 
-g (non-const+    } 
-</code> +    if (!aa.owner_before(std::weak_ptr<A>{}) && !std::weak_ptr<A>{}.owner_before(aa)) { 
- +      std::cout << "empty4\n";  // False 
-On ne respecte la l'obligation d'appeler des méthodes ''const'' depuis une méthode ''const''+    } 
- +    if (aa.expired()) { 
-===Cas avec un pointeur unique et propagate_const=== +      std::cout << "expired4\n"; 
- +    } 
-Prérequis minimum clang 3.9, gcc 6.1. Pas dans Visual Studio 2017 [[https://github.com/jbcoe/propagate_const|sauf sur GitHub]]. +  } 
- +  return 0; 
-<code cpp> +}
-#include <experimental/propagate_const> +
-  std::experimental::propagate_const<std::unique_ptr<X>> m_ptrX; +
-</code> +
- +
-Rendu : +
- +
-<code> +
-f (non-const) +
-g (non-const) +
-f (const) +
-g (const)+
 </code> </code>
lang/cpp/smartptr.1573165762.txt.gz · Dernière modification : de root