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/10/17 09:19] – [Préserver l'attribut const sur les pointeurs] rootlang:cpp:smartptr [2024/01/11 17:00] (Version actuelle) – Ajout de "Différencier empty et expired" root
Ligne 1: Ligne 1:
-====std::weak_ptr en tant que clé dans un conteneur==== +{{ :lang:cpp:smartptr:cpp_smart_pointers_ebook.pdf |C++ smart pointers fluentcpp}} 
-Il faut utiliser le comparateur ''owner_less''.+ 
 +====Durée de vie==== 
 + 
 +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(...)''
 <code cpp> <code cpp>
-std::map<U, T, std::owner_less<U>> destination;+#include <iostream> 
 +#include <memory> 
 + 
 +class A { 
 + public: 
 +  A() { std::cout << "Constructor\n";
 +  ~A() { std::cout << "Destructor\n";
 +}; 
 + 
 +int main() { 
 +  std::shared_ptr<Aa = std::make_shared<A>(); 
 +  a.reset(new A()); 
 +  a = std::make_shared<A>(); 
 +
 +</code> 
 + 
 +Sortie : 
 + 
 +<code> 
 +Constructor 
 +Constructor 
 +Destructor 
 +Constructor 
 +Destructor 
 +Destructor
 </code> </code>
  
 ====Préserver l'attribut const sur les pointeurs==== ====Préserver l'attribut const sur les pointeurs====
-Il faut utiliser ''propagate_const''.+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}}).
  
 Soit la classe commune ''X'' : Soit la classe commune ''X'' :
Ligne 33: Ligne 62:
 </code> </code>
  
-===Cas avec la classe ''X'' intégrée dans une classe ''Y''===+  * Cas avec la classe ''X'' intégrée dans une classe ''Y'' avec pointeur classique
  
 <code cpp> <code cpp>
Ligne 68: Ligne 97:
 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''. 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 unique===+  * Cas avec un pointeur intelligent
  
 <code cpp> <code cpp>
Ligne 100: Ligne 129:
 </code> </code>
  
-On ne respecte la l'obligation d'appeler des méthodes ''const'' depuis une méthode ''const''.+On ne respecte l'obligation d'appeler des méthodes ''const'' depuis une méthode ''const''.
  
-===Cas avec un pointeur unique et propagate_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]]. Prérequis : minimum clang 3.9, gcc 6.1. Pas dans Visual Studio 2017 [[https://github.com/jbcoe/propagate_const|sauf sur GitHub]].
Ligne 118: Ligne 147:
 f (const) f (const)
 g (const) g (const)
 +</code>
 +
 +====Encapsuler fopen/close====
 +
 +<code cpp>
 +std::unique_ptr<FILE, decltype(&fclose)> fp(std::fopen(filename.c_str(), "r"), &fclose);
 +</code>
 +
 +[[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}}
 +
 +====weak_ptr====
 +
 +====std::weak_ptr en tant que clé dans un conteneur====
 +Il faut utiliser le comparateur ''owner_less''.
 +<code cpp>
 +std::map<U, T, std::owner_less<U>> destination;
 +</code>
 +
 +===Différencier empty et expired===
 +
 +Sans passer par ''.lock()'' pour ''empty()''.
 +
 +<code cpp>
 +#include <iostream>
 +#include <memory>
 +
 +class A {};
 +
 +int main() {
 +  {
 +    std::weak_ptr<A> aa;
 +
 +    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";
 +    }
 +  }
 +
 +  {
 +    std::shared_ptr<A> a;
 +    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::weak_ptr<A> aa;
 +    {
 +      std::shared_ptr<A> a = std::make_shared<A>();
 +      aa = a;
 +
 +      if (!aa.owner_before(std::weak_ptr<A>{}) && !std::weak_ptr<A>{}.owner_before(aa)) {
 +        std::cout << "empty3\n";  // False
 +      }
 +      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;
 +}
 </code> </code>
lang/cpp/smartptr.1571296781.txt.gz · Dernière modification : 2019/10/17 09:19 de root