ダブルディスパッチ
なにやら難しい言葉だがやってる事は簡単である。
struct Zaku{}; struct Char_zaku : public Zaku{}; struct Gundam{ void say(const Zaku&) const{ std::cout << "相手がザクなら!人間じゃないんだ、ぼくだって" << std::endl; } void say(const Char_zaku&) const{ std::cout << "撃つぞ・・・撃つぞ・・・撃つぞぉぉぉ!" << std::endl; } };
引数の型によって処理を変更したい場合があるとする。
呼び出し側は以下のようになる。
Zaku zaku; Char_zaku char_zaku; Gundam gundam; gundam.say(zaku); // Gundam::say(const Zaku&) が呼ばれる gundam.say(char_zaku); // こっちも問題なく呼び出される
つまり、ダブルディスパッチとは、実行時の型によって異なる関数を呼び出す為の機構である。
C++だと関数のオーバーロードを利用して行っている。
よく理解していなかったので改めて調べてみたら単なるバズワードだった。
また、以下のような場合には注意が必要である。
Zaku& zaku = Char_zaku(); Gundam gundam; gundam.say(zaku); // Gundam::say(const Zaku&) が呼ばれる // 本当は Gundam::say(const Char_zaku&) が呼ばれて欲しい
この場合は、自分を渡すような処理を追加して対応する。
struct Zaku{ virtual void call_say(const Gundam& gundam){ gundam.say(*this); } }; struct Char_zaku : public Zaku{ virtual void call_say(const Gundam& gundam){ gundam.say(*this); } };
Zaku& zaku = Char_zaku();
Gundam gundam;
zaku.call_say(gundam); // 問題なく Gundam::say(const Char_zaku&) が呼ばれる
これで問題なく呼ばれる。
続く…?