2013-06-12 10 views
6

Questa è una domanda su come implementare alcune esigenze che ho avuto ultimamente. Sono sicuro che esiste un modello o una soluzione comune per questo e, anche se ne ho avuto uno, sono ansioso di saperne di più.Metodi C++ in classi derivate con parametri diversi

Supponiamo che io stia lavorando in un gioco in cui tutte le entità correlate al gioco stesso derivino da una classe "Attore" (diciamo "ostacolo", "ostacolo in movimento", "proiettile" e "cannone"). Nel gioco, tutte le entità sono memorizzate in un vettore std::vector<Actor *> in modo che possano essere attraversate.

Ora, supponiamo che ogni "attore" possa "fare" qualcosa ad ogni turno e diamo loro un "atto" di metodo. Obstacle :: act farebbe poco, Moving_obstacle :: act e Projectile :: act li sposterebbe e "Cannon :: act" creerebbe un nuovo proiettile. E 'una sorta di senso avere una funzione virtuale pura Attore :: agire in modo da poter a sua volta fare qualcosa di simile:

std::vector<Actor *>::iterator b=myvectorofactors.begin(), e=myvectorofactors.end(); 
while(b < e) 
{ 
    *b->act(); 
    b++; 
} 

E li hanno tutti "agire". Bene, finora tutto bene ... Il fatto è che Cannon :: act potrebbe avere un prototipo diverso o un valore di ritorno (per esempio, per memorizzare un proiettile generato e averlo spinto nel vettore) e questa "piccola" differenza rompe tutto.

Ora, so che da un certo punto di vista questi sovraccarichi di metodo sono funzioni completamente diverse ciascuno. So anche che si può sempre pianificare in anticipo e ingegnare attraverso il problema con sufficiente lungimiranza ... O si può semplicemente manovrare il problema.

In questo caso, ho appena usato diversi identificatori univoci per ogni classe di attori derivati ​​e li ho usati per trasmettere alla corrispondente classe e fare il lavoro che li circonda. Sono sicuro che tornerò lo stesso problema ancora una volta e sono curioso di sapere su alcune soluzioni entry level.

Grazie in anticipo per il vostro tempo.

+0

meno muro di testo, altro esempio di codice, si prega di – David

+3

non sono d'accordo @ Dave, è un pozzo domanda ponderata. – Nick

+0

Si potrebbe voler guardare il [modello visitatore] (http://en.wikipedia.org/wiki/Visitor_pattern). – Nick

risposta

3

La partenza è suono, è deragliare qui:

Il fatto è che, Cannon :: atto potrebbe avere un prototipo diverso o valore di ritorno (per esempio, per memorizzare un proiettile generato e averlo inserito nel vettore)

Perché dovrebbe? L'atto è atto. L'istanza deve capirlo senza altro. Dovrai addestrarlo nel ctor o altre chiamate prima di agire. O si guarderà intorno durante la chiamata Act.

Considera: anche se hai magicamente caricato il carico utile per diversi parametri, nel preventivo mentre come sarebbe stato calcolato? La chiamata è astratta. Anche se l'hai infestato da qualche dynamic_cast, lasci comunque il problema con quale cannone otterrà quali parametri?

No, i soggetti devono cooperare tra di loro, o usare qualche sistema di messaggistica (vedi dispatcher) ...

+0

Un sistema di messaggistica è proprio quello che ho usato in un altro progetto. Finito per essere troppo contorto - probabilmente una cattiva implementazione - quindi sono andato a provare qualcosa di diverso ... Ho notato la deraling (molto, ogni volta che guardo il codice) ma non ho mai pensato di allenarlo in qualche altro metodo. Ci penserà nei progetti futuri. Grazie. –

+0

Contrassegnato come risposta. Non che nessun commento sia stato di aiuto, ma il "Act is act" mi ha davvero conquistato. Proprio per FYI ho smantellato l'intera eredità difettosa e ho scritto diversi metodi nelle sottoclassi del controller di gioco e degli attori per lavorare con ogni caso particolare (sparare, spostare altri attori o qualsiasi altra cosa). Discernere tra le classi usando il metodo whats_my_type_id è brutto, ma abbastanza lontano per questo progetto. –

1

le variabili interne che il corpo di ogni atto è diverso e possono utilizzare la variabile interna privata di proprietà o ereditata, quindi se è possibile impostare queste variabili prima di chiamare act, quindi non è necessario inviare nulla tramite parametro per essere sicuri, o di non entrare in complicazioni

+0

Grazie per la risposta ... Il fatto è, immagina di voler aggiungere un nuovo "proiettile": Beh, dovrei o restituirlo da qualche parte o passare un riferimento/puntatore per me scrivere in ... Suppongo di poterlo fare senza problemi, ma poi di nuovo, vorrei finire con il static_casting della classe "Actor", così posso chiamare questi metodi di preparazione. Qualche idea al riguardo? –

+0

puoi avere tutti i comandi della classe base con un parametro pointer, che viene utilizzato solo da istanze interessate e invia un valore null a coloro che non devono restituire nulla, – aah134

+0

Questo è ciò che avevo effettivamente nella mia classe "Cannon". Scriverà sul puntatore quando firing con successo e quindi il controller principale controllerebbe se c'era qualcosa in quel puntatore in modo che potesse essere inserito nel vettore Actor ... Tuttavia, avevo bisogno di molti più tipi di parametri. Per fortuna l'ho già risolto: vedi i commenti sopra. –

Problemi correlati