2012-01-24 13 views
6

In una porzione di codice legacy con cui mi è stato chiesto di lavorare, ho trovato un concetto che non capisco. Cercare in SO e googling non è stato di grande aiuto, quindi questa domanda.Ricavare una classe template da sé in C++

C'è una classe template che assomiglia a questo:

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 classe CmdHandlerBase è una classe non-template che esiste altrove in un colpo di testa diversa. A seguito della definizione di cui sopra, v'è una macro che assomiglia a questo:

#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; } \ 
    }; 

assomiglia al di sopra macro si specializza in parte il modello di classe CommandHandlerGeneric. È corretto? Qual è la logica alla base di una classe privata derivata da se stessa?

risposta

3

Non riesco davvero a fare nulla del tuo esempio specifico, ma in generale, quello è un modello di classe ricorsivo. Ci dovrebbe essere una specializzazione in giro per Index_t = x, che terminerebbe la ricorsione.

Il secondo ingrediente qui è l'ereditarietà privata, che può essere considerata come form of composition. Combinato con un modello ricorsivo, è possibile utilizzarlo per creare una classe di dimensioni variabili, ad esempio un vettore di una certa dimensione.

+3

* Ci dovrebbe essere una specializzazione in giro per Index_t = 0 *, o qualche altro valore –

+0

Destra, modificato. –

+0

Molte grazie ragazzi! – Somesh

2

Nota questo:

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

Il primo parametro del modello è alterato. Non è più la stessa classe. Un modello di classe non è una classe completa fino a quando non vengono specificati tutti i parametri.

In effetti, è illegale ereditare dallo stesso modello di classe e passare lo stesso set di parametri, ma non è questo il caso.

+0

Grazie per averlo indicato. Tuttavia, perché qualcuno dovrebbe voler fare una cosa del genere? Quale scopo serve? – Somesh

+1

@Somesh: Questo è un po 'di concatenamento, immagino, non posso dirlo senza scavare nel codice. – sharptooth

Problemi correlati