Domanda

I Pimpl sono una fonte di boilerplate in un sacco di codice C ++. Sembrano il tipo di cosa che una combinazione di macro, modelli e forse un piccolo aiuto esterno potrebbe risolvere, ma non sono sicuro di quale sarebbe il modo più semplice. Ho visto dei modelli che aiutano a fare un po 'di sollevamento ma non molto: alla fine devi ancora scrivere le funzioni di inoltro per ogni metodo della classe che stai cercando di racchiudere. C'è un modo più semplice?

Sto immaginando uno strumento usato come parte del processo di creazione. Vuoi che le tue intestazioni pubbliche siano classi pimpl'd, quindi fornisci un file di input, ad esempio pimpl.in, che elenca le classi (implementate non-pimpl'd) che desideri avvolgere, quindi quel file viene esaminato, le classi pimpl vengono generate e solo le loro intestazioni (non le intestazioni della classe originale) vengono installate durante un 'make install'. Il problema è che non vedo alcun modo di farlo senza un parser C ++ completo, qualcosa che nemmeno i venditori di compilatori possono ottenere. Forse le classi potrebbero essere scritte in qualche modo, il che rende più semplice il lavoro di uno strumento esterno, ma sono sicuro che finirò per perdere tutti i tipi di casi angolari (ad esempio classi e / o funzioni dei membri modelli).

Qualche idea? Qualcun altro ha già trovato una soluzione a questo problema?

È stato utile?

Soluzione

No, non c'è una risposta facile. :-( Penserei con quasi tutti gli esperti OO che dicono "preferisco la composizione rispetto all'eredità", ci sarebbe supporto linguistico per rendere la composizione molto più semplice dell'eredità.

Altri suggerimenti

Non sto dicendo che questo è buono (solo qualcosa che mi è venuto in mente).
Ma potresti provare a sovraccaricare l'operatore - >

#include <memory>
#include <iostream>

class X
{
    public:
    void plop()
    {
        std::cout << "Plop\n";
    }
};

class PimplX
{
    public:
        PimplX()
        {
            pimpl.reset(new X);
        }
        X* operator->()
        {
            return pimpl.get();
        }
    private:
        PimplX(PimplX const&);
        PimplX& operator=(PimplX const&);
        std::auto_ptr<X>    pimpl;
};   


int main()
{    
    PimplX      x;

    x->plop();
}

Un'opzione è utilizzare invece una classe di interfaccia:

class ClassA {
  virtual void foo() = 0;
  static ClassA *create();
};

// in ClassA.cpp

class ImplA : public ClassA {
/* ... */
};
ClassA *ClassA::create() {
  return new ImplA();
}

Questo aggiunge comunque un sovraccarico dal recupero dei puntatori della funzione vtable.

A parte questo, non riesco a pensare a nessuno di questi strumenti. Come hai detto, l'analisi di C ++ non è banale e ci sono altre lingue là fuori dove è meno un problema (ad esempio, C # o Java ritardano il tutto, in modo da poter modificare il loro layout in memoria in seguito senza problemi).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top