Outils pour utilisateurs

Outils du site


helloworld:design_pattern:pont:cpp

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
helloworld:design_pattern:pont:cpp [2019/11/07 23:30] – Ajout des sources roothelloworld:design_pattern:pont:cpp [2025/10/30 15:20] (Version actuelle) – Détail de l'implémentation de pimpl root
Ligne 1: Ligne 1:
-Interface (entête) :+Interface (entête) du pimpl :
 <code cpp> <code cpp>
 +#pragma once
 +
 #include <memory> #include <memory>
  
 class Fridge class Fridge
 { {
-public: + public: 
-   Fridge(); +  Fridge(); 
-   void coolDown(); +  Fridge(const Fridge& other) = delete; 
-private: +  Fridge(Fridge&&); 
-   class FridgeImpl; +  Fridge& operator=(const Fridge& other) = delete; 
-   std::unique_ptr<FridgeImpl> impl_;+  Fridge& operator=(Fridge&&); 
 +  ~Fridge(); 
 +  void coolDown(); 
 + private: 
 +  class FridgeImpl; 
 +  std::unique_ptr<FridgeImpl> impl_;
 }; };
 </code> </code>
Ligne 22: Ligne 29:
 class Fridge::FridgeImpl class Fridge::FridgeImpl
 { {
-public: + public: 
-   void coolDown() +  void coolDown() 
-   +  
-      std::cout << "coucou\n"; +    std::cout << "coucou\n"; 
-   +  
-private: + private: 
-   int engine_;+  int engine_;
 }; };
  
 Fridge::Fridge() : impl_(new FridgeImpl()) {} Fridge::Fridge() : impl_(new FridgeImpl()) {}
 +Fridge::Fridge(Fridge&&) = default; 
 +Fridge& Fridge::operator=(Fridge&&) = default;
 +Fridge::~Fridge() = default;
 void Fridge::coolDown() { impl_->coolDown(); } void Fridge::coolDown() { impl_->coolDown(); }
 </code> </code>
Ligne 38: Ligne 48:
  
 {{ :lang:cpp:smartptr:cpp_smart_pointers_ebook.pdf |C++ smart pointers fluentcpp}} {{ :lang:cpp:smartptr:cpp_smart_pointers_ebook.pdf |C++ smart pointers fluentcpp}}
 +
 +[[https://en.cppreference.com/w/cpp/language/pimpl.html|PImpl]] {{ :helloworld:design_pattern:pont:cpp:pimpl_-_cppreference.com_10_30_2025_1_00_24_pm_.html |Archive le 30/10/2025}}
 +
 +=====Détail====
 +
 +Pourquoi tout ça ?
 +
 +====Version de base====
 +
 +<code cpp>
 +#include <memory>
 +
 +class A {
 +   private:
 +    struct Aimpl;
 +    std::unique_ptr<Aimpl> impl;
 +};
 +
 +int main() { auto p = std::make_unique<A>(A{}); }
 +</code>
 +
 +Erreur : ''error: invalid application of 'sizeof' to incomplete type 'A::Aimpl%%'%%''.
 +
 +====Version 2====
 +
 +Il faut empêcher de mettre ''inline'' le constructeur et le destructeur.
 +
 +<code cpp>
 +#include <memory>
 +
 +class A {
 +   public:
 +    A();
 +    ~A();
 +
 +   private:
 +    struct Aimpl;
 +    std::unique_ptr<Aimpl> impl;
 +};
 +
 +int main() { auto p = std::make_unique<A>(A{}); }
 +</code>
 +
 +Erreur : ''copy constructor of 'A' is implicitly deleted because field 'impl' has a deleted copy constructor''.
 +
 +====Version 3====
 +
 +Ajout du constructeur et de l'opérateur ''move''.
 +
 +<code cpp>
 +#include <memory>
 +
 +class A {
 +   public:
 +    A();
 +    ~A();
 +    A(A&&) = default; 
 +    A& operator=(A&&) = default;
 +
 +   private:
 +    struct Aimpl;
 +    std::unique_ptr<Aimpl> impl;
 +};
 +
 +int main() {
 +    auto p = std::make_unique<A>(A{});
 +}
 +</code>
 +
 +Erreur : ''invalid application of 'sizeof' to incomplete type 'A::Aimpl%%'%%''.
 +
 +====Version 4====
 +
 +Même problème que ''Version 2''. Il faut enlever le ''inline'' au constructeur et à l'opérateur ''move''.
 +
 +
 +<code cpp>
 +#include <memory>
 +
 +class A {
 +   public:
 +    A();
 +    A(A&&); 
 +    A& operator=(A&&);
 +    ~A();
 +
 +   private:
 +    struct Aimpl;
 +    std::unique_ptr<Aimpl> impl;
 +};
 +
 +int main() {
 +    auto p = std::make_unique<A>(A{});
 +}
 +</code>
 +
 +Il faut bien sûr implémenter ''A::A()'', ''A::~A()'', ''A::A(A&&)'', ''A& A::operator=(A&&)'' dans le ''.cpp''.
helloworld/design_pattern/pont/cpp.1573165830.txt.gz · Dernière modification : de root