ダブルディスパッチは関数のオーバーロード以上である
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2017/12/19 13:38 UTC 版)
「ダブルディスパッチ」の記事における「ダブルディスパッチは関数のオーバーロード以上である」の解説
一見したところでは、ダブルディスパッチは関数のオーバーロードの自然な結果である。関数のオーバーロードは呼び出されるクラスだけではなく、引数の型にも応じて呼び出しが行われるようにすることができるが、オーバーロードされた関数の呼び出しはほぼ一つの仮想関数テーブルを通じて行われるため、動的なディスパッチは呼び出すオブジェクトの種類によってのみ決まる。下記の例において、あるゲームで衝突の判定を行う場合を考える。 class SpaceShip {};class GiantSpaceShip : public SpaceShip {};class Asteroid {public: virtual void CollideWith(SpaceShip&) { cout << "Asteroid hit a SpaceShip" << endl; } virtual void CollideWith(GiantSpaceShip&) { cout << "Asteroid hit a GiantSpaceShip" << endl; }};class ExplodingAsteroid : public Asteroid {public: virtual void CollideWith(SpaceShip&) { cout << "ExplodingAsteroid hit a SpaceShip" << endl; } virtual void CollideWith(GiantSpaceShip&) { cout << "ExplodingAsteroid hit a GiantSpaceShip" << endl; }}; ここで、 Asteroid theAsteroid;SpaceShip theSpaceShip;GiantSpaceShip theGiantSpaceShip; があるとすると、関数のオーバーロードのために theAsteroid.CollideWith(theSpaceShip); theAsteroid.CollideWith(theGiantSpaceShip); 上記のコードは、動的なディスパッチを使用せず、 Asteroid hit a SpaceShip および Asteroid hit a GiantSpaceShip とそれぞれ表示する。 さらに、 ExplodingAsteroid theExplodingAsteroid;theExplodingAsteroid.CollideWith(theSpaceShip); theExplodingAsteroid.CollideWith(theGiantSpaceShip); 上記のコードはExplodingAsteroid hit a SpaceShip およびExplodingAsteroid hit a GiantSpaceShip と、やはり動的なディスパッチを使用せずに表示する。 Asteroidに対する参照を使って動的なディパッチを用いると、 Asteroid& theAsteroidReference = theExplodingAsteroid;theAsteroidReference.CollideWith(theSpaceShip); theAsteroidReference.CollideWith(theGiantSpaceShip); ExplodingAsteroid hit a SpaceShip および ExplodingAsteroid hit a GiantSpaceShipと期待通りに表示する。 しかし、 SpaceShip& theSpaceShipReference = theGiantSpaceShip;theAsteroid.CollideWith(theSpaceShipReference); theAsteroidReference.CollideWith(theSpaceShipReference); は、Asteroid hit a SpaceShip および ExplodingAsteroid hit a SpaceShipと表示するが、これはいずれも正しくない。問題は、仮想関数が C++ によって動的にディスパッチが行われるのに対して、関数のオーバーロードは静的に行われるためである。
※この「ダブルディスパッチは関数のオーバーロード以上である」の解説は、「ダブルディスパッチ」の解説の一部です。
「ダブルディスパッチは関数のオーバーロード以上である」を含む「ダブルディスパッチ」の記事については、「ダブルディスパッチ」の概要を参照ください。
- ダブルディスパッチは関数のオーバーロード以上であるのページへのリンク