Ho già fatto innumerevoli volte: è uno scenario molto comune. C'è un numero di cose che faccio praticamente sempre.
Non preoccuparti troppo di renderlo la cosa più efficiente disponibile.
Se finiamo di perdere un sacco di tempo per impacchettare e svuotare i pacchetti, possiamo sempre cambiarlo per renderlo più efficiente. Anche se non ho ancora riscontrato un caso in cui ho dovuto, non ho implementato router di rete!
Anche se l'utilizzo di structs/unions è l'approccio più efficiente in termini di tempo di esecuzione, viene fornito con una serie di complicazioni: convincere il compilatore a comprimere le strutture/i sindacati in modo che corrispondano alla struttura di ottetti dei pacchetti necessari, evitare problemi di allineamento e endianità e mancanza di sicurezza poiché non vi è alcuna o minima opportunità di effettuare controlli di integrità sui build di debug.
spesso finiscono con un'architettura che include i seguenti tipi di cose: classe base
- Un pacchetto. Tutti i campi dati comuni sono accessibili (ma non modificabili).Se i dati non sono memorizzati in un formato compresso, allora c'è una funzione virtuale che produrrà un pacchetto impacchettato.
- Un numero di classi di presentazione per tipi di pacchetti specifici, derivati dal tipo di pacchetto comune. Se stiamo usando una funzione di impacchettamento, allora ogni classe di presentazione deve implementarla.
- Tutto ciò che può essere dedotto dal tipo specifico della classe di presentazione (ad esempio un ID di tipo di pacchetto da un campo dati comune), viene gestito come parte dell'inizializzazione ed è altrimenti non modificabile.
- Ogni classe di presentazione può essere costruita da un pacchetto decompresso, oppure fallisce correttamente se i dati del pacchetto non sono validi per quel tipo. Questo può quindi essere confezionato in una fabbrica per comodità.
- Se non è disponibile RTTI, è possibile ottenere "RTTI di poor-man" utilizzando l'id del pacchetto per determinare quale specifica classe di presentazione è realmente un oggetto.
In tutto questo, è possibile (anche se solo per le build di debug) verificare che ogni campo che è modificabile sia impostato su un valore corretto. Anche se potrebbe sembrare molto lavoro, rende molto difficile avere un pacchetto formattato in modo non valido, un contenuto di pacchetti preconfezionati può essere facilmente controllato a occhio utilizzando un debugger (poiché è tutto in normali variabili di formato nativo della piattaforma).
Se dobbiamo implementare uno schema di archiviazione più efficiente, anche questo può essere racchiuso in questa astrazione con costi di prestazioni aggiuntivi minimi.
Ero sicuro di aver visto un quasi duplicato di questo, ma non riuscivo a scavare. Le risposte nel link correlato non sono buone come quelle qui, ma comunque ... – dmckee