0Pricing
C++ Academy · Lezione

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

  1. Librerie header-only e compilate a confronto
  2. Versionamento delle API e stabilità dell'ABI
  3. Nascondere l'implementazione con PIMPL
  4. Scrivere una moderna libreria di utilità header-only
← Torna a C++ Academy