Nascondere l'implementazione con PIMPL
Nasconda i dettagli implementativi dietro l'idioma pointer-to-implementation
Nascondere l'implementazione con PIMPL è una lezione C++ Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C++ Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C++ Academy include 4 lezioni in totale.
L'idiom PIMPL
PIMPL = «Pointer to IMPLementation», ossia «puntatore all'implementazione». Sposti i dati privati della classe in una struct impl separata, accessibile tramite un puntatore.
Perché usare PIMPL?
Vantaggi:
- Nascondere i dettagli dell'implementazione negli header
- Ridurre le dipendenze in fase di compilazione
- Mantenere stabile l'ABI quando si aggiungono membri privati
- Consentire la sostituzione delle implementazioni
Struttura di base
La classe pubblica contiene un puntatore a una struct Impl definita esclusivamente nel file .cpp.
// widget.h
class Widget {
public:
Widget();
~Widget();
void doSomething();
private:
struct Impl;
std::unique_ptr<Impl> pimpl_;
};Impl nel file .cpp
La struct Impl contiene tutti i dati effettivi.
// widget.cpp
struct Widget::Impl {
std::string name;
int counter;
// ... anything else, freely
};
Widget::Widget()
: pimpl_(std::make_unique<Impl>()) {}
Widget::~Widget() = default; // must be in .cpp where Impl is complete
void Widget::doSomething() {
pimpl_->counter++;
}Distruttore nel file cpp
Il distruttore deve essere definito nel file .cpp, dove Impl è completo. In caso contrario, unique_ptr non può eliminare un tipo incompleto.
Funzioni membro speciali
Anche copia, spostamento e assegnazione devono essere dichiarati esplicitamente, se necessari. Le versioni generate dal compilatore non possono funzionare con un tipo incompleto nell'header.
// widget.h
class Widget {
public:
Widget(const Widget& other);
Widget& operator=(const Widget& other);
Widget(Widget&&) noexcept;
Widget& operator=(Widget&&) noexcept;
~Widget();
};Costo in termini di prestazioni
PIMPL aggiunge un'indirezione a ogni accesso a un membro e un'allocazione sull'heap. Per i metodi chiamati frequentemente questo può essere significativo: misuri per avere conferma.
Build più veloci
Gli header che prima includevano tipi della libreria standard o dipendenze costose possono ora essere più snelli. Modifichi il file .cpp senza ricompilare i consumer.
PIMPL con l'ereditarietà
È possibile combinarlo con l'ereditarietà, ma ciò aggiunge complessità. In genere la classe pubblica non deriva da nulla; Impl può utilizzare liberamente l'ereditarietà.
Varianti
Alternative e perfezionamenti:
- Fast PIMPL — memoria inline con placement new
- Indirizzo stabile — Impl rimane allocato per tutta la durata dell'oggetto
- Type erasure — Impl può essere polimorfico
Utilizzo reale
PIMPL è ampiamente utilizzato da:
- Qt (ogni widget usa PIMPL)
- Molte librerie proprietarie
- Boost (in alcune parti)
Quando usarlo
Utilizzi PIMPL quando:
- Desidera stabilità ABI tra le versioni
- I suoi header includono transitivamente troppe dipendenze
- Espone un'API di libreria pubblica
Quando evitarlo
Eviti PIMPL quando:
- La classe è interna: nessun consumer dipende dall'header
- L'overhead delle prestazioni è più importante dei tempi di build
- La classe è piccola o viene modificata raramente
Verifica rapida
Perché il distruttore di una classe PIMPL deve essere definito nel file .cpp?
Riepilogo
PIMPL nasconde l'implementazione spostando i dati privati in una struct Impl accessibile tramite unique_ptr. Migliora la stabilità ABI e i tempi di build al costo di un'indirezione. Definisca le funzioni membro speciali nel file .cpp, dove Impl è completo.
Domande Frequenti
La lezione «Nascondere l'implementazione con PIMPL» è gratuita?
Sì — il testo completo di «Nascondere l'implementazione con PIMPL» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C++ Academy, passa a CoddyKit PRO. Il corso C++ Academy include 4 lezioni in totale.
Cosa imparerò in «Nascondere l'implementazione con PIMPL»?
Nasconda i dettagli implementativi dietro l'idioma pointer-to-implementation Eserciti C++ Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare C++ Academy?
Non è richiesta alcuna esperienza precedente. C++ Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «Nascondere l'implementazione con PIMPL»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione C++ Academy?
Sì. Ogni lezione C++ Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Librerie header-only e compilate a confronto
- Versionamento delle API e stabilità dell'ABI
- Nascondere l'implementazione con PIMPL
- Scrivere una moderna libreria di utilità header-only