¿Dónde definir los funtores utilizados por muchas clases derivadas?

Un escenario común en mi código es que obtuve un funtor que es utilizado por muchas clases en una jerarquía.

Para que sea accesible para todas las clases y permanezca SECO, generalmente lo defino como una estructura interna protegida de mi clase base así:

class Base
{
protected:
    struct CommonFunctor
    {
        bool operator()()
        {
            return true;
        }
    };
};

class DerivedA : public Base
{
    void FooA()
    {
        bool test = CommonFunctor()();
    }
};

class DerivedB : public Base
{
    void FooB()
    {
        bool test = CommonFunctor()();
    }
};

No me gusta esa solución porque satura mi clase base con muchos pequeños funtores, que son solo internos e incluso si no son accesibles al público, disminuyen la legibilidad de mi clase base.

¿Conoces alguna otra solución para este escenario?

preguntado el 22 de mayo de 12 a las 08:05

¿Cuál es el problema de que se definan en el mismo espacio de nombres que las clases con las que trabajan? -

¿Por qué no simplemente declarar el funtor? operator()() en la definición de clase y definir el funtor en otro lugar? -

@hmjd: Eso es lo que hice. Solo fusioné la definición y la declaración para mi ejemplo de código. Todavía hay mucho desorden en mi archivo de encabezado de clase base... -

@GeneBushuyev: Tiene razón: podría declarar todos esos funtores dentro de mi espacio de nombres en un archivo de encabezado separado como CommonFunctors.h e incluirlo en todas mis clases derivadas. ¿Es esto lo que quisiste decir? -

3 Respuestas

Simplemente implemente sus funtores en archivos nuevos (BaseClassFunctors.cpp + BaseClassFunctors.h). Póngalos dentro de su espacio de nombres con subespacios de nombres opcionales (por ejemplo, espacio de nombres main.internal).

Ahora incluye el archivo de encabezado en cualquier clase derivada que desee, sin saturar el encabezado de la clase base.

contestado el 23 de mayo de 12 a las 06:05

Por mucho que yo (y, aparentemente, todos los demás) odiemos la herencia múltiple, sería útil aquí.

Simplemente cree una segunda clase que contenga todos sus funtores y en sus clases secundarias derivadas de Base, heredar ambos Base y esta nueva clase.

contestado el 22 de mayo de 12 a las 08:05

Nunca pensé en usar la herencia múltiple para eso. Gracias por una nueva visión. - nabulke

Espero que responda a su pregunta. Otra solución sería hacer que su clase de funtor se derive de Base, luego derivar DerivedA y DerivedB de la clase funtor solo. Menos limpio, más hacky. - Mahmoud Al-Qudsi

Esta es sin duda una respuesta a mi pregunta. Me pregunto si hay otras soluciones por ahí.... - nabulke

Medios de derivación es un relación, nada que ver con los funtores. - gen bushuyev

@Gene no importa qué derivación significa tanto como funciona y lo que le permite hacer. Si te hace sentir mejor, llama a la clase ConsumerOfManyFunctors y entonces DerivedA y DerivedB y puede derivar de ella, si eso te hace sentir mejor sabiendo que puedes decir DerivedA es un ConsumerOfManyFunctors. - Mahmoud Al-Qudsi

Simplemente puede implementar el funtor en otro lugar y aún así mantenerlo como miembro de la Base:

class Base
{
protected:
    struct CommonFunctor;
};   

struct Base::CommonFunctor
{
    bool operator()()
    {
        return true;
    }
};

contestado el 22 de mayo de 12 a las 09:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.