0

さて、私はもう一度レンガを打ちました..再び、それが間違っている理由がわかりませんし、それを機能させる方法がわかりません:

クラスHumanのインスタンスがあります。HumanクラスはObjectから派生しています。Objectクラスには、「PerformStep」という仮想関数があります。Humanクラスは、この関数をオーバーロードします。 ヒューマンクラスにも「WalkAction」という機能があります。ここで、PerformStep - By メンバー関数ポインターの間に、この「walkaction」を呼び出したいと思います。
私はポインタでこれを行うのが好きです:
人間は愚かです: 彼らは歩き方を知っていますが、いつ. そのため、ステップ中に神のインスタンスが尋ねられます。「今何をすべきか」-そして、その神のインスタンスは正しいメンバー関数へのポインターを返します。

virtual void PerformStep() 
{
    postion.x += 0; //redundant line to check for the debugger
    CALL_MEMBER_FN(*this,&Human::WalkAction);
    Object::PerformStep();
}

ヒューマン::ウォークアクション:

void WalkAction(){
    position.x += 1;
}

CALL_MEMBER_FN (マクロ):
CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))

問題は、プログラムをデバッグ モードで実行すると、関数ポインタのある行が完全に無視されることです。-ステートメントごとに実行すると、行を「ジャンプ」します。ウォークアクションにブレークポイントを配置すると、ブレークポイントに到達しません。特定の行にブレークポイントを配置すると、ブレークポイントは次の行に移動しますライン。

ここで何が起きてるの?

4

1 に答える 1

6

このマクロはこのコンテキストでは何もしません。関数へのポインターに展開されるだけです。実際に関数を呼び出すには、追加の括弧のペアが必要です。

myObj->myfunc;   // does nothing
myObj->myFunc(); // calls the function 

コンパイラがこれを最適化したことを期待しているので、実行したり中断したりするコードはありません。あなたはこれをはっきりと見ることができます:

  • そもそもマクロを使用しない(推奨)
  • コンパイラのオプションを使用して、対応するアセンブラとインターリーブされたソースコードを出力します。
于 2010-11-22T21:04:29.647 に答える