C ++ Typecasting VS performance

4

Diciamo che stiamo progettando un videogioco. Abbiamo alcuni sprite sulla mappa e vogliamo chiamare qualche metodo del particolare sprite in una posizione particolare.

Stiamo utilizzando un framework C ++ ampiamente noto . Ha una classe GraphicsItem e TUTTI i nostri sprite ne derivano. Ora, framework ha un metodo per ottenere un puntatore del GraphicsItem in qualsiasi posizione sulla mappa.

Ora abbiamo due opzioni:

  1. Trasmetti da GraphicsItem* al nostro Sprite* e chiama il metodo Sprite . (Sappiamo per certo che tutti gli elementi grafici sulla mappa sono istanze di Sprite )

  2. Crea alcune cose pazze come memorizza i puntatori su Sprite in un contenitore, esegui iterate su di esse, confronta le valute degli indirizzi e ottieni il Sprite* senza casting.

La domanda è: qual è la migliore pratica in questo caso? Mi è stato sempre detto di evitare il typecasting perché significa che hai problemi di progettazione. Ma come posso cambiare design per evitare la tipizzazione qui? E l'iterazione extra su un contenitore con un confronto è solo ... pazza ...

    
posta Kolyunya 26.02.2013 - 03:23
fonte

2 risposte

5

Se sai che tutto nella scena è un'istanza di Sprite , non ci dovrebbero essere problemi con typecasting. Puoi abilitare RTTI e usare dynamic_cast<Sprite *> per essere più sicuro.

Se potrebbero esserci altri elementi GraphicsItem che non sono istanze di Sprite , allora potresti mantenere un set (forse QSet<GraphicsItem *> ) che contiene puntatori alle istanze di Sprite che dovrebbero apparire nella scena. Quando ottieni un puntatore dalla scena, controlla per accertarti che si trovi nel set di sprite. Questo ha lo svantaggio di richiedere che tu mantenga il set insieme alla manutenzione della scena stessa.

Certamente non sarebbe necessario creare un contenitore di mappatura che mappasse un GraphicsItem * a un Sprite * .

    
risposta data 26.02.2013 - 03:40
fonte
4

Un cast implicito per il primo tipo di base e il cast statico inverso per il tipo derivato quando si è certi che quel tipo sia esattamente zero operazioni in fase di esecuzione. Non puoi batterlo.

Un cast implicito a un tipo non primo base e il cast statico inverso a un tipo derivato che ha come base non primo un semplice incremento / decremento con un controllo di puntatore nullo. Ha un costo, ma è banale e non lo batterai con nessuna ricerca.

Un cast dinamico legge il puntatore della tabella del metodo virtuale dall'oggetto, lo confronta con quello della classe di destinazione e se si esegue il casting su ciò che è ancora di base del tipo effettivo, segue una serie di puntatori per controllarlo. Un costo un po 'più alto, ma è improbabile che tu possa batterlo con qualsiasi tipo di ricerca.

Quindi, con tutti i mezzi cast. Usa il cast dinamico se devi controllare il tipo (il tipo base deve avere almeno un membro virtuale perché funzioni, ma è certamente il caso qui).

Sì, se devi digitare il cast, di solito significa che hai problemi di progettazione. Ma in questo caso non sono i tuoi problemi di progettazione. Se la libreria fornisce un mezzo per specificare la propria classe base derivata dall'interfaccia di cui ha bisogno la libreria e la restituisce (tramite il template), si può fare con metodi virtuali, possibilmente utilizzando il patter dei visitatori da lì. Purtroppo no, quindi devi lanciare. Se lo desideri, puoi avvolgere la tela nella tua classe che eseguirà il casting e avvolgerà anche l'inserimento per garantire che tutti gli elementi siano effettivamente sprite.

    
risposta data 26.02.2013 - 10:36
fonte

Leggi altre domande sui tag