I modelli C++ sono noti per l'utilizzo di tipi come argomenti, ma possono anche essere parametrizzati su altri tipi di dati. Ad esempio, è possibile templatize una classe sopra un intero, come illustrato di seguito:
template <typename T, unsigned int N> class Array {
private:
T array[N];
public:
/* ... */
};
I modelli possono anche essere parametrizzati su puntatori, fino a quando il puntatore soddisfa determinati criteri (ad esempio, si deve valutare a un indirizzo di qualcosa che può essere determinato in fase di compilazione).Ad esempio, questo è perfettamente legale:
template <int* Pointer> class ThisIsLegal {
public:
void doSomething() {
*Pointer = 137;
}
};
Nel codice, il modello è parametrizzato nel corso di un puntatore-a-class-membro. Un membro pointer-to-class è simile a un puntatore in quanto indirettamente si riferisce ad un oggetto. Tuttavia, invece di puntare a un oggetto, punta invece a un campo in una classe. L'idea è che è possibile dereferenziare un membro puntatore-a-classe relativo a qualche oggetto per selezionare quel campo fuori dalla classe. Ecco un semplice esempio di puntatori-to-Class-membro:
struct MyStruct {
int x, y;
};
int main() {
MyStruct ms;
ms.x = 137;
ms.y = 42;
int MyStruct::* ptr; // Declare a pointer to a class member.
ptr = &MyStruct::x; // Now points to the field 'x'
ms.*ptr = 0; // Set the 'x' field of ms to be zero.
}
Si noti che la sintassi per dichiarare un puntatore-a-class-membro è
Type ContainingClass::* pointerName;
Così nel codice qui sopra, int MyStruct::* ptr
mezzi . "un puntatore ad un int
all'interno di una classe di MyStruct
Nel codice che hai postato, la dichiarazione modello di legge come questo:
template <
class PropObject,
class PropType,
PropType PropObject::* Prop
>
class PropReader
Vediamo cosa significa. I primi due oggetto argomento template di cui verrà letta la proprietà e PropType
, il tipo di tale proprietà. "L'argomento finale del modello è un membro puntatore alla classe denominato Prop
che punta all'interno di uno PropObject
in un campo di digitare PropType
Ad esempio, è possibile creare un'istanza per questo modello con MyStruct
in questo modo:.
PropReader<MyStruct, int, &MyStruct::x> myPropReader;
Ora, vediamo quello che il resto del codice fa il corpo di questo modello di classe è ristampato qui:.
void print(Object& o)
{
PropObject& po = static_cast<PropObject &>(o);
PropType& t = po.*Prop;
cout << t << "\n";
}
Alcuni di questi possono essere letti abbastanza facilmente. a questa funzione si riferisce un Object
denominato o
e l'ultima riga stampa un campo. Queste due linee sono difficili:
PropObject& po = static_cast<PropObject &>(o);
PropType& t = po.*Prop;
Questa prima riga è un typecast che dice "cerca di lanciare l'argomento o
ad un riferimento di tipo PropObject
L'idea, sto cercando di indovinare, è che Object
è una certa classe di base. di molti oggetti diversi.Il parametro della funzione è semplicemente un Object
, e questo cast tenta di convertirlo in qualcosa del tipo appropriato (ricorda che PropObject
è l'argomento del modello che dice qual è il tipo di oggetto). questo utilizza static_cast
, se la conversione non è definita (ad esempio, si è tentato di creare un'istanza del modello su int
o vector<string>
), il codice non verrà compilato. e, il codice si fida che il cast sia sicuro, quindi ottiene un riferimento di tipo PropObject
a cui si riferisce il parametro.
Infine, l'ultima riga è
PropType& t = po.*Prop;
Questo utilizza la sintassi dereference puntatore-a-class-membro ho detto prima a dire "selezionare il campo puntato dal Prop
(l'argomento template), poi negozio un riferimento ad esso chiamato t
.
Così, in breve, il modello
- ti chiede il tipo di un oggetto.
- Richiede il tipo di campo in quell'oggetto.
- Richiede un puntatore al campo in quell'oggetto.
- Fornisce una funzione
print
che a un oggetto tenta di stampare quel campo.
Whew! E 'stato difficile! Spero che questo ti aiuti!
Questa è stata una risposta sorprendente templatetypedef .. non mi sorprende che tu abbia quel nome utente :) – cgcoder