http://d.hatena.ne.jp/fkm/20061125/p1
インターフェースにするとDoOkeyAction()の実装の部分で、インターフェースを実装してるクラスのフィールドとかメソッドとかを使って何かしたあとstate_->DoOkeyAction(this);とできる。
が正解。StateがState保持者であるContextに対して影響を与える必要がある場合、Contextのinterfaceを知っていないといけない。
SetState以外にもたとえば、
interface HogeContext { void 逃げる(); void 攻撃(); void SetState(HogeState s); } interface HogeState { void 攻撃された(HogeContext *c); } class 強気State : HogeState { void 攻撃された(HogeContext *c) { if (HPヤバイ) { s = new 弱気State(); c->SetState(s); s->攻撃された(c); } else { c->攻撃(); } } } class 弱気State : HogeState { void 攻撃された(HogeContext *c) { c->逃げる(); } }
となる。
だから、
thisで実装しているクラス(のインスタンス)のポインタが渡せるということは、危険な香りがするがdynamic_castで元に戻せる?
をしてはダメ。dynamic_castするんじゃなくて、Stateからアクセスできる関数はinterfaceで宣言しないと、Contextがinterfaceになっている理由がなくなっちゃう。
ちなみに、State保持者であるContextは一つだけである事が多いので、Stateクラスはコンストラクタで保持者であるContextへの参照をもらえば、毎回引数としてContextを受け取る必要はない。