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 [2022/10/18 13:32] – Ajout de "Durée de vie" 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 33: Ligne 33:
 </code> </code>
  
-====std::weak_ptr en tant que clé dans un conteneur==== + 
-Il faut utiliser le comparateur ''owner_less''.+====Encapsuler fopen/close==== 
 <code cpp> <code cpp>
-std::map<U, T, std::owner_less<U>> destination;+std::unique_ptr<FILEdecltype(&fclose)> fp(std::fopen(filename.c_str(), "r"), &fclose);
 </code> </code>
  
-====Préserver l'attribut const sur les pointeurs==== +[[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}}
-Il faut utiliser ''std::propagate_const<std::unique_ptr<X%%>>%%''.+
  
-Il existe aussi ''indirect_value'' qui peut se substituer à ''std::propagate_const<std::unique_ptr<X%%>>%%''. Attention, ''indirect_value'' ne permet pas de se substituer à ''std::propagate_const<std::shared_ptr<X%%>>%%'' (voir [[https://github.com/jbcoe/indirect_value/issues/106|Can I replace shared_ptr by indirect_value ?]] {{ :lang:cpp:smartptr:can_i_replace_shared_ptr_by_indirect_value_issue_106_jbcoe_indirect_value_github_18_10_2022_13_27_26_.html |Archive du 04/08/2022 le 18/10/2022}}). +====weak_ptr====
- +
-Soit la classe commune ''X'' :+
  
 +====std::weak_ptr en tant que clé dans un conteneur====
 +Il faut utiliser le comparateur ''owner_less''.
 <code cpp> <code cpp>
-struct X +std::map<U, T, std::owner_less<U>> destination;
-+
-  void g() const { std::cout << "g (const)\n";+
-  void g() { std::cout <"g (non-const)\n";+
-};+
 </code> </code>
  
-et le programme commun :+===Différencier empty et expired=== 
 + 
 +Sans passer par ''.lock()'' pour ''empty()''.
  
 <code cpp> <code cpp>
-int main() +#include <iostream> 
-+#include <memory>
-  Y y; +
-  y.f();+
  
-  const Y cy; +class A {};
-  cy.f(); +
-}+
  
-</code>+int main() { 
 +  { 
 +    std::weak_ptr<Aaa;
  
-  * Cas avec la classe ''X'' intégrée dans une classe ''Y'' avec pointeur classique +    if (!aa.owner_before(std::weak_ptr<A>{}) && !std::weak_ptr<A>{}.owner_before(aa)) { 
- +      std::cout << "empty1\n"; 
-<code cpp+    } 
-struct Y +    if (aa.expired()) { 
-{ +      std::cout << "expired1\n"; 
-  Y() { }+    } 
 +  }
  
-  void f() const 
   {   {
-    std::cout << "f (const)\n"+    std::shared_ptr<A> a
-    m_ptrX.g(); +    std::weak_ptr<A> aa = a;
-  }+
  
-  void f() +    if (!aa.owner_before(std::weak_ptr<A>{}) && !std::weak_ptr<A>{}.owner_before(aa)) { 
-  +      std::cout << "empty2\n"; 
-    std::cout << "f (non-const)\n"; +    
-    m_ptrX.g();+    if (aa.expired()) { 
 +      std::cout << "expired2\n" // False 
 +    }
   }   }
  
-  // Ici, X est une instance sans pointeur. 
-  X m_ptrX; 
-}; 
-</code> 
- 
-Rendu sans surprise : 
- 
-<code> 
-f (non-const) 
-g (non-const) 
-f (const) 
-g (const) 
-</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''. 
- 
-  * Cas avec un pointeur intelligent 
- 
-<code cpp> 
-struct Y 
-{ 
-  Y() : m_ptrX{} { } 
- 
-  void f() const 
   {   {
-    std::cout << "f (const)\n"+    std::weak_ptr<A> aa
-    m_ptrX->g(); +    
-  }+      std::shared_ptr<A> a = std::make_shared<A>(); 
 +      aa = a;
  
-  void f() +      if (!aa.owner_before(std::weak_ptr<A>{}&& !std::weak_ptr<A>{}.owner_before(aa)) { 
-  { +        std::cout << "empty3\n";  // False 
-    std::cout << "(non-const)\n"; +      } 
-    m_ptrX->g();+      if (aa.expired()) 
 +        std::cout << "expired3\n";  // False 
 +      } 
 +    } 
 +    if (!aa.owner_before(std::weak_ptr<A>{}&& !std::weak_ptr<A>{}.owner_before(aa)) { 
 +      std::cout << "empty4\n";  // False 
 +    
 +    if (aa.expired()) { 
 +      std::cout << "expired4\n"; 
 +    }
   }   }
- +  return 0
-  std::unique_ptr<X> m_ptrX+}
-}+
-</code> +
- +
-Rendu : +
- +
-<code cpp> +
-f (non-const) +
-g (non-const) +
-f (const) +
-g (non-const) +
-</code> +
- +
-On ne respecte l'obligation d'appeler des méthodes ''const'' depuis une méthode ''const''+
- +
-  * Cas avec un pointeur unique et propagate_const +
- +
-Prérequis : minimum clang 3.9, gcc 6.1. Pas dans Visual Studio 2017 [[https://github.com/jbcoe/propagate_const|sauf sur GitHub]]. +
- +
-<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.1666092747.txt.gz · Dernière modification : de root