Diciamo che ho una classe chiamata Country e due sottoclassi chiamate AI e Player. La classe Paese ha un numero di metodi virtuali per consentire comportamenti specifici del giocatore o specifici dell'IA.
Voglio che il giocatore possa cambiare nazione durante una partita. A tal fine, sto rifattando la relazione ereditaria con la composizione. Quindi potrò cambiare l'istanza interna del Paese di un giocatore per un altro in qualsiasi momento.
Questo solleva un po 'un problema: quando un oggetto esterno tenta di chiamare uno di questi metodi virtuali su un Player, viene delegato correttamente al metodo Paese dopo che è stata elaborata qualsiasi elaborazione appropriata fatto. Ma quando un metodo interno chiama uno dei metodi virtuali, il codice nella versione Player o AI non ha più possibilità di essere eseguito.
Quindi ora mi rimane l'aggiornamento di ognuno di questi metodi per assicurarmi che entrambe le versioni siano chiamate, il che di per sé non è un compito banale (loop infiniti, chiunque?).
Questo sembra molto più difficile di quanto dovrebbe essere. Ho già fatto dei refactoring simili e non ho mai avuto questo problema. Perché? Mi manca qualche osservazione apparentemente ovvia?
Modifica per un esempio concreto ora che ho di nuovo accesso al codice:
class Country
{
public:
virtual void AddMoney(float money)
{
_vMoney += money;
}
void TakeLoan()
{
float loan = ...;
AddMoney(loan); // <-- does not route through AI or Player implementation
}
}
class AI // : public Country
{
private:
Country *pCountry;
public:
virtual void AddMoney(float x)
{
pCountry->AddMoney(x); // formerly Country::AddMoney(x)
AllocateMoney(x);
}
}