34

メンバ関数へのポインタのリストがありますが、それらの関数を呼び出すのに苦労しています...適切な構文は何ですか?

typedef void (Box::*HitTest) (int x, int y, int w, int h);

for (std::list<HitTest>::const_iterator i = hitTestList.begin(); i != hitTestList.end(); ++i)
{
    HitTest h = *i;
    (*h)(xPos, yPos, width, height);
}

また、ここにメンバー関数を追加しようとしています

std::list<HitTest> list;

for (std::list<Box*>::const_iterator i = boxList.begin(); i != boxList.end(); ++i)
{
    Box * box = *i;
    list.push_back(&box->HitTest);
}
4

4 に答える 4

48

非静的メンバー関数へのポインターは、固有の呼び出し構文を持つ固有の野獣です。

これらの関数を呼び出すには、名前付きパラメーターだけでなくthisポインターも提供する必要があるため、Boxとして使用されるポインターを手元に用意する必要がありますthis

(box->*h)(xPos, yPos, width, height);
于 2013-02-11T14:33:49.753 に答える
13

メンバー関数へのポインターを介してメンバー関数を呼び出すには、特定の構文があります。

(obj.*pmf)( params );   //  Through an object or reference.
(ptr->*pmf)( params );  //  Through a pointer.

オーバーライドすることはできますが->*、標準ライブラリのイテレータには含まれていません(おそらく、すべての可能な関数型に対してオーバーライドが必要になるためです)。したがって、イテレータだけがある場合は、それを逆参照して、最初の形式を使用する必要があります。

((*iter).*pmf)( params );

一方、メンバー自体へのポインターを反復処理しても、この問題は発生しません。

(objBox.*(*i))( params );   //  If objBox is an object
(ptrBox->*(*i))( params );  //  If ptrBox is a pointer

(の周りに括弧は必要ないと思いますが、*iメンバー構文へのポインターはすでに十分に特別です。)

于 2013-02-11T14:59:56.593 に答える
10

私の「受賞歴」から;-)デリゲートについての回答(https://stackoverflow.com/questions/9568150/what-is-ac-delegate/9568226#9568226で入手可能):

次のようなメンバー関数へのポインタをTypedefします。

typedef void (T::*fn)( int anArg );

次のように宣言します。

fn functionPtr = &MyClass::MyFunction

このように呼んでください:

(MyObject.*functionPtr)( argument );
于 2013-02-11T15:00:13.440 に答える
1

オブジェクトを介してメンバー関数ポインターを取得しようとすると、誤解が生じます。メンバー関数ポインターには、呼び出すオブジェクトへのポインターは含まれません。呼び出しの時点でそのようなポインターを提供する必要があります。

多くの人が指摘しているように、メンバー関数呼び出しの構文は次のいずれかです。

 obj.*funcptr(args);

また

 objptr->*funcptr(args);

あなたが与えた例では、本当に必要なのは仮想関数のようです。多くの異なるタイプのオブジェクトで呼び出す必要がある標準操作 (オブジェクトがボックスと交差するかどうかを検出する) があり、そのタイプはコンパイル時にわかりません。これは、仮想機能のために切り取られたジョブです。

于 2013-02-11T15:20:04.790 に答える