2009-02-24 19 views
5

Ho un buffer char (ad esempio byte) che sto inviando tramite la rete. Ad un certo punto in futuro potrei voler cambiare il buffer in un tipo diverso come unsigned char o short. Ho pensato di fare qualcosa di simile:Uso valido di typedef?

typedef char bufferElementType; 

E ogni volta che faccio qualcosa con un elemento di buffer dichiaro come bufferElementType piuttosto che char. In questo modo potrei passare ad un altro tipo modificando questo typedef (ovviamente non sarebbe così semplice, ma sarebbe almeno facile identificare i luoghi che devono essere modificati ... ci sarà un bufferElementType nelle vicinanze) .

È valido/valido l'uso di typedef? Non ne vale la pena? Mi darà un mal di testa ad un certo punto nel futuro? Farà in modo che i programmatori di manutenzione mi odiano?

ho letto attraverso When Should I Use Typedef In C++, ma nessuno realmente trattato questo.

+0

Si utilizzano array di questo tipo per i buffer? O vuoi dire che il buffer è lungo 1 byte, e potresti desiderare di renderlo 2 byte o 4 byte in futuro? –

+0

In questo caso, non c'è molto vantaggio nell'usare "typedef char bufferElementType;". Se si utilizza la stessa dimensione di matrice ovunque, potrebbe essere utile digitare typedef l'intero tipo di array: "typedef char [1024] bufferElementType;" - che ti permette di cambiare la dimensione del buffer ovunque in un colpo solo. –

+0

Se tuttavia i buffer sono realmente in grado di contenere "caratteri di testo" e si sta considerando di passare da una codifica di caratteri esattamente a 1 byte (ad esempio ANSI) a una codifica di caratteri esattamente a 2 byte o esattamente a 4 byte, allora l'originale typedef è la strada da percorrere. –

risposta

11

È un ottimo (e normale) utilizzo. Bisogna stare attenti, però, che, ad esempio, il tipo selezionato soddisfi gli stessi criteri firmati/non firmati o che rispondano in modo simile agli operatori. Quindi sarebbe più facile cambiare il tipo in seguito.

Un'altra opzione è quella di utilizzare i modelli per evitare che fissa il tipo fino al momento in cui si sta compilando. Una classe che viene definita come:

template <typename CharType> 
class Whatever 
{ 
    CharType aChar; 
    ... 
}; 

è in grado di lavorare con qualsiasi tipo char si seleziona, mentre risponde a tutti gli operatori nello stesso modo.

+0

Non capisco quali siano i vantaggi dell'uso di typedef in questo caso. L'unico scopo della variabile buffer è di fornire un dato numero di byte di memoria, e char è sempre la dimensione della più piccola unità di memoria indirizzabile. Puoi dare uno scenario in cui la modifica del tipo typedefed sarebbe utile? –

+0

char a wchar, ad esempio; char a XMLChar (libxml2), ecc. Riconosco che il caso di un solo char non è il più interessante, ma dare dei nomi che descrivono semanticamente i tipi è anche una buona pratica, a parte gli altri motivi che ho dato. –

+0

Sì, questo è un caso d'uso. Ho avuto la sensazione dalla domanda del richiedente che era interessato a un buffer di * byte *, ma se si suppone che tenga caratteri di testo in alcune codifiche (a dimensione fissa ma eventualmente multibyte), allora è appropriato considerare diversi tipi di elementi buffer. –

1

Sì, questo è l'utilizzo ideale per typedef, almeno in C.

per C++ si può sostenere che i modelli sono un'idea migliore (come Diego Sevilla ha suggerito) ma hanno i loro svantaggi. (Lavoro extra se tutto ciò che utilizza il tipo di dati non è già racchiuso in alcune classi, tempi di compilazione più lenti e una struttura di file sorgente più complessa, ecc.)

Ha anche senso combinare i due approcci, cioè dare un nome typedef a un parametro template.

Si noti che quando si inviano dati su una rete, il tipo di carattere e altri tipi di interi non possono essere intercambiabili (ad esempio a causa di endianità). In tal caso, l'utilizzo di una classe basata su modelli con funzioni specializzate potrebbe avere più senso. (Inviare <char> invia il byte, inviare <breve> converte in rete ordine dei byte prima)

Un'altra soluzione potrebbe essere quella di creare una classe "BufferElementType" con i metodi helper (convertToNetworkOrderBytes()), ma scommetto sarebbe un eccesso per te.

2

Un altro vantaggio di typedef è che, se usati con saggezza, possono aumentare la leggibilità. Come esempio davvero stupido, un metro e una laurea possono essere entrambi doppi, ma ti piacerebbe distinguere tra loro. Utilizzando un typedef è onc veloce & soluzione facile a make errors more visible.

Nota: una soluzione più robusta all'esempio precedente sarebbe stata creare tipi diversi per un metro e un grado. Pertanto, il compilatore può far rispettare le cose da solo. Ciò richiede un po 'di lavoro, che comunque non sempre ripaga.L'uso di typedefs è un modo rapido & per rendere gli errori visibili, come descritto nell'articolo collegato sopra.

+0

typedef può sicuramente aumentare la leggibilità, tuttavia non possono rendere gli errori più visibili in quanto sono solo alias che il compilatore traduce immediatamente nel loro tipo sottostante. Quindi se Meter e Degree sono entrambi tipizzati per raddoppiare, il codice "Meter x; Degree y; x = y;" compila senza errori. –

+0

Non ho mai sostenuto il contrario. È molto meglio se il compilatore può applicarlo da solo. Ma questo richiede più codice. Una soluzione rapida e facile è renderla visibile agli HUMANS - vedi l'articolo collegato per ulteriori informazioni. –

+0

Abbastanza giusto. Puoi evitare l'assegnazione diretta accidentale tra tipi usando "class Meter {double _x; public: Meter (double x): _x (x) {}; operator double &() {return _x;}};" e lo stesso per Laurea; ma questo ancora consente ad es. "Contatore x; Grado y; x = y + 5;". Questo può anche essere evitato, ma è più difficile. –