Pregunta

Los pimpl son una fuente de repetición en muchos códigos C ++. Parecen el tipo de cosas que una combinación de macros, plantillas y, quizás, una pequeña herramienta externa podrían resolver, pero no estoy seguro de cuál sería la forma más fácil. He visto plantillas que ayudan a hacer algo del levantamiento pero no mucho: aún tendrá que escribir funciones de reenvío para cada método de la clase que está tratando de ajustar. ¿Hay alguna forma más fácil?

Estoy imaginando una herramienta utilizada como parte del proceso de creación. Desea que sus encabezados públicos sean clases integradas, de modo que proporcione un archivo de entrada, digamos pimpl.in, que enumera las clases (implementadas sin pimpl'd) que desea ajustar, luego se examina ese archivo. las clases de pimpl se generan y solo se instalan sus encabezados (no los encabezados de la clase original) durante una 'instalación'. El problema es que no veo ninguna forma de hacer esto sin un analizador de C ++ completo, algo que incluso los proveedores de compiladores no pueden hacer bien. Tal vez las clases podrían escribirse de alguna manera que facilite el trabajo de una herramienta externa, pero estoy seguro de que terminaría perdiendo todo tipo de casos de esquina (por ejemplo, clases con plantilla y / o funciones de miembro con plantilla).

¿Alguna idea? ¿Alguien más ya tiene una solución para este problema?

¿Fue útil?

Solución

No, no hay una respuesta fácil. :-( Creo que con casi todos los expertos en OO que dicen "preferir la composición a la herencia", habría soporte de idioma para hacer que la composición sea mucho más fácil que la herencia.

Otros consejos

No estoy diciendo que esto sea bueno (solo algo que me vino a la mente).
Pero podría experimentar con la sobrecarga del operador - >

#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();
}

Una opción es usar una clase de interfaz en su lugar:

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

// in ClassA.cpp

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

Sin embargo, esto agrega sobrecarga al obtener los punteros de la función vtable.

Aparte de eso, no puedo pensar en ninguna de esas herramientas. Como dijo, el análisis de C ++ no es trivial, y hay otros lenguajes por ahí donde es un problema menor (por ejemplo, C # o Java retrasar todo, así que puede cambiar su diseño en la memoria más adelante sin problemas).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top