En un diseño de una jerarquía de clases, estoy usando una clase base abstracta que declara varios métodos que implementarían las clases derivadas. En cierto sentido, la clase base está lo más cerca posible de una interfaz en C++. Sin embargo, hay un problema específico. Considere el siguiente código que declara nuestra clase de interfaz:Tipo abstracto devuelto en la clase base
class Interface {
public:
virtual Interface method() = 0;
};
class Implementation : public Interface {
public:
virtual Implementation method() { /* ... */ }
};
Por supuesto, esto no sería compilar, porque no se puede volver una clase abstracta en C++. Para solucionar este problema que estoy usando la siguiente solución:
template <class T>
class Interface {
public:
virtual T method() = 0;
};
class Implementation : public Interface<Implementation> {
public:
virtual Implementation method() { /* ... */ }
};
esta solución funciona y es todo lo fino y elegante, sin embargo, para mí, no se ve muy elegante, debido al poco redundante de texto cuál sería el parámetro para la interfaz. Me alegraría si ustedes pudieran señalar nuestros otros problemas técnicos con este diseño, pero esa es mi única preocupación en este momento.
¿Hay alguna manera de deshacerse de ese parámetro de plantilla redundante? Posiblemente usando macros?
Nota: El método en cuestión tiene que devolver una instancia. Soy consciente de que si method()
devolviera un puntero o una referencia, no habría ningún problema.
El modismo que está aplicando se denomina [Patrón de plantilla curiosamente recurrente] (http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Curiously_Recurring_Template_Pattern).Supongo que podrías reemplazar la declaración de clase con macro como '#define DERIVE_TEMPLATE_BASE (Derivada, Base) class Derivada: public Base', pero parece extremadamente feo y probablemente confundirá tu editor. En resumen, sí, hay una redundancia, pero está bien establecida y es un modismo reconocible. –
gwiazdorrr
@gwiazdorrr: Eso no parece tan malo. Si es un modismo reconocido, entonces puedo asumir que no será demasiado desconocido para los usuarios de la "interfaz", ¿correcto? – Zeenobit
También tenga en cuenta que (al menos en este ejemplo), no tiene sentido hacer que las llamadas sean virtuales, ya que CRTP requiere que se conozca el tipo más derivado para usar el tipo base. –