2012-01-24 11 views
6

En una parte del código heredado con el que me pidieron que trabaje, me encontré con un concepto que no entiendo. La búsqueda en SO y en Google no ayudó del todo, de ahí esta pregunta.Derivar una clase de plantilla de sí mismo en C++

Hay una clase de plantilla que tiene este aspecto:

template<int Index_t, int Kind_t, ProtocolType Prot_t, class Protocol> 
class CommandHandlerGeneric 
    : private CommandHandlerGeneric<Index_t-1, Kind_t, Prot_t, Protocol> { 
public: 
    CommandHandlerGeneric(Protocol& Shared, CmdHandlerBase** Cont) : 
     CommandHandlerGeneric<Index_t-1, Kind_t, Prot_t, Protocol>(Shared, Cont) {} 
}; 

La clase es una clase CmdHandlerBase no molde que existe en un encabezado diferente en otro lugar. Siguiendo la definición anterior, existe una macro que tiene este aspecto:

#define REGISTER_COMMAND_HANDLER_BASE(CmdIndex, CmdType, CmdKind, ProtType) \ 
    template<class Protocol> \ 
    class CommandHandlerGeneric<CmdIndex, CmdKind, ProtType, Protocol> 
     : private CommandHandlerGeneric<CmdIndex-1, CmdKind, ProtType, Protocol> \ 
    { \ 
     CmdType m_Cmd;\ 
    public: \ 
     CommandHandlerGeneric(Protocol& Shared, CmdHandlerBase** Cont) : \ 
     m_Cmd(Shared), \ 
     CommandHandlerGeneric<CmdIndex-1, CmdKind, ProtType, Protocol>(Shared, Cont) \ 
     { Cont[CmdIndex] = &m_Cmd; } \ 
    }; 

se parece a la macro anterior se especializa en parte la plantilla de clase CommandHandlerGeneric. ¿Es esto correcto? ¿Cuál es la razón detrás de derivar una clase en privado de sí mismo?

Respuesta

3

Realmente no puedo hacer nada de su ejemplo específico, pero en general, es una plantilla de clase recursiva. Debería haber una especialización alrededor para Index_t = x, que terminaría la recursión.

El segundo ingrediente aquí es la herencia privada, que se puede considerar como form of composition. Combinado con una plantilla recursiva, puede usar esto para crear una clase de tamaños variables, por ejemplo un vector de cierta dimensión.

+3

* Debería haber una especialización alrededor de Index_t = 0 *, o algún otro valor –

+0

Right, cambió eso. –

+0

Muchas gracias chicos! – Somesh

2

Nota esto:

template<int Index_t, int Kind_t, ProtocolType Prot_t, class Protocol> 
class CommandHandlerGeneric 
    : private CommandHandlerGeneric<Index_t-1, Kind_t, Prot_t, Protocol> 

se altera El primer parámetro de plantilla. Ya no es la misma clase. Una plantilla de clase no es una clase completa hasta que se hayan especificado todos los parámetros.

De hecho, es ilegal heredar de la misma plantilla de clase y pasar el mismo conjunto de parámetros, pero ese no es el caso aquí.

+0

Gracias por señalarlo. Sin embargo, ¿por qué alguien querría hacer tal cosa? ¿Para qué sirve? – Somesh

+1

@Somesh: Eso es algo de encadenamiento que supongo, no puedo decir sin profundizar en el código. – sharptooth

Cuestiones relacionadas