一般に、共分散により、派生クラスのインターフェイスでは、基本クラスのインターフェイスよりも多くの情報を表現できます。派生クラスの動作は基本クラスの動作よりも具体的であり、共分散は違い (の 1 つの側面) を表します。
一部のクライアントが基本クラス インターフェイスを使用したいが、他のクライアントは派生クラス インターフェイスを使用する状況で、ガビンの関連する階層がある場合に役立ちます。const-correctness を省略した場合:
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();
};
自分が WebPage を持っていることを知っているクライアント (おそらくブラウザー) は、クエリ パラメータを調べることに意味があることを知っています。Resource 基本クラスを使用しているクライアントは、そのようなことを知りません。それらは常に返さHttpAddress&
れたものをURI&
変数または一時にバインドします。
Resource オブジェクトに HttpAddress があると思われるが、わからない場合は、dynamic_cast
. しかし、共分散は、静的型付けがまったく有用であるのと同じ理由で、「知っているだけ」でキャストを行うよりも優れています。
代替手段があります-getQueryParam
関数をオンにしますURI
がhasQueryParam
、すべてに対してfalseを返すようにします(URIインターフェースを乱雑にします)。WebPage::getIdentifier
return を定義したままにしURL&
、実際にはを返し、HttpIdentifier&
発信者に無意味なことをさせますdynamic_cast
(呼び出しコードを混乱させ、「返された URL は HttpAddress に動的にキャスト可能であることが保証されている」と言う WebPage のドキュメント)。getHttpIdentifier
に機能を追加しますWebPage
(インターフェースを乱雑にしWebPage
ます)。または、それが意図していることに共分散を使用するだけWebPage
です。FtpAddress
MailtoAddress
HttpAddress
最後に、もちろん、関連するガビンの階層は言うまでもなく、ガビンの階層を持つべきではないという合理的な議論があります。しかし、これらのクラスは、純粋仮想メソッドとのインターフェイスとして簡単に使用できるため、共分散を使用する有効性には影響しないと思います。