Interface (entête) du pimpl :
#pragma once
#include
class Fridge
{
public:
Fridge();
Fridge(const Fridge& other) = delete;
Fridge(Fridge&&);
Fridge& operator=(const Fridge& other) = delete;
Fridge& operator=(Fridge&&);
~Fridge();
void coolDown();
private:
class FridgeImpl;
std::unique_ptr impl_;
};
Implémentation (source) :
#include "Fridge.h"
#include
class Fridge::FridgeImpl
{
public:
void coolDown()
{
std::cout << "coucou\n";
}
private:
int engine_;
};
Fridge::Fridge() : impl_(new FridgeImpl()) {}
Fridge::Fridge(Fridge&&) = default;
Fridge& Fridge::operator=(Fridge&&) = default;
Fridge::~Fridge() = default;
void Fridge::coolDown() { impl_->coolDown(); }
[[https://herbsutter.com/gotw/_100/|GotW #100: Compilation Firewalls]] {{ :helloworld:design_pattern:pont:cpp:gotw_100_compilation_firewalls_difficulty_6_10_sutter_s_mill_2019-11-07_23_16_52_.html |Archive du 27/11/2011 le 07/11/2019}}
{{ :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====
#include
class A {
private:
struct Aimpl;
std::unique_ptr impl;
};
int main() { auto p = std::make_unique(A{}); }
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.
#include
class A {
public:
A();
~A();
private:
struct Aimpl;
std::unique_ptr impl;
};
int main() { auto p = std::make_unique(A{}); }
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''.
#include
class A {
public:
A();
~A();
A(A&&) = default;
A& operator=(A&&) = default;
private:
struct Aimpl;
std::unique_ptr impl;
};
int main() {
auto p = std::make_unique(A{});
}
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''.
#include
class A {
public:
A();
A(A&&);
A& operator=(A&&);
~A();
private:
struct Aimpl;
std::unique_ptr impl;
};
int main() {
auto p = std::make_unique(A{});
}
Il faut bien sûr implémenter ''A::A()'', ''A::~A()'', ''A::A(A&&)'', ''A& A::operator=(A&&)'' dans le ''.cpp''.