In generale, la covarianza consente di esprimere più informazioni nell'interfaccia di classe derivata rispetto a quella reale nell'interfaccia di classe base. Il comportamento di una classe derivata è più specifico di quello di una classe base e la covarianza esprime (un aspetto della) la differenza.
È utile quando si hanno gerarchie correlate di gubbins, in situazioni in cui alcuni client desiderano utilizzare un'interfaccia di classe base, ma altri client utilizzeranno l'interfaccia di classe derivata.Con const correttezza omesso:
class URI { /* stuff */ };
class HttpAddress : public URI {
bool hasQueryParam(string);
string &getQueryParam(string);
};
class Resource {
virtual URI &getIdentifier();
};
class WebPage : public Resource {
virtual HttpAddress &getIdentifier();
};
I clienti che sanno di avere una pagina web (browser, forse) sapere che è significativo per guardare ai parametri di query. I client che utilizzano la classe di base delle risorse non conoscono questa cosa. Legheranno sempre il valore restituito HttpAddress&
a una variabile URI&
o temporanea.
Se sospettano, ma non sanno, che il loro oggetto Risorsa ha un indirizzo Http, possono dynamic_cast
. Ma la covarianza è superiore a "conoscere solo" e fare il cast per la stessa ragione per cui la tipizzazione statica è utile a tutti.
Esistono alternative: attivare la funzione getQueryParam
su URI
ma rendere hasQueryParam
restituire false per tutto (ingombrare l'interfaccia URI). Lasciare WebPage::getIdentifier
definito per restituire URL&
, restituendo effettivamente un valore HttpIdentifier&
e fare in modo che i chiamanti facciano un inutile dynamic_cast
(ingombrare il codice chiamante e la documentazione di WebPage in cui si dice "l'URL restituito è garantito per essere digitalizzabile in HttpAddress"). Aggiungere una funzione getHttpIdentifier
a WebPage
(ingombra l'interfaccia WebPage
). O semplicemente usa la covarianza per quello che è destinato a fare, che è esprimere il fatto che uno WebPage
non ha uno FtpAddress
o uno MailtoAddress
, ha uno HttpAddress
.
Infine c'è ovviamente un ragionevole argomento che non si dovrebbero avere gerarchie di gubbins, per non parlare delle gerarchie correlate di gubbins. Ma quelle classi potrebbero facilmente essere interfacce con metodi virtuali puri, quindi non penso che influenzi la validità dell'uso della covarianza.
fonte
2009-08-11 16:04:54
Quando ho letto la domanda la mia reazione era esattamente la stessa. Qual è il problema: non utilizzare i tipi di ritorno covarianti! –