-1

これを使用しstd::bindてクラス外の関数をバインドし、奇妙な動作をします。

プライベートメンバー変数の値をいくらか制御します。

//MClass.h
typedef std::function<void(void)> Action;

class MClass {

public:

  Action OnLeftClick;

//some other functions here

private:
  int totalContents;

  VScrollbar* _vscrollbar;

};

//MClass.cpp

この種の実装では、バグは発生しません。

MClass::MClasss() {

  OnLefClick = std::bind(&VScrollbar::Scrolldown, this);

}

//but when I do this
//otherfile.h

MClass mclass;

void clickBar() {

  mclass.totalContents = 0;

}

void InitComponentns() {   

mclass.OnLeftClick = std::bind(clickBar, mclass);

}

OnLeftClick()そして、それに割り当てられた関数を呼び出すときはいつでもclickBar()、の値はtotalContents0に変更されません(totalContents値はMClassの他の関数によって増分されます)。

私はここで何か間違ったことをしていますか?

4

2 に答える 2

1

呼び出しのthis引数は、std::bind実際には関数の最初の引数です。メンバー関数の場合、これは、関数がメンバーであるクラスのインスタンスである必要があります。すべてのメンバー関数には、thisポインターである最初の引数が隠されているためです。

したがって、コードが機能するには、 の最初の引数はではなく、クラスVScrollbar::Scrolldownのインスタンスである必要があります。そのようです:VScrollbarthisMClass

OnLefClick = std::bind(&VScrollbar::Scrolldown, _vscrollbar);

2 番目のstd::bind呼び出しでは、引数を取らない関数であるため (非表示かどうかに関係なく)、関数ポインターのみを渡す必要があります。

mclass.OnLeftClick = std::bind(clickBar);

totalContentsただし、メンバー変数はプライベートであり、関数からアクセスできないため、質問のコードがビルドされることに驚いていclickBarます。

于 2013-02-18T11:41:32.450 に答える
1

まず、mclass を clickBar にバインドすることはできません。これは、関数が引数を取らないためです。への参照を取るように関数を変更できますMClass

void clickBar(MClass& m) { m.totalContents = 42; }

次に、できたとしても、bind は mclass のコピーを作成します。std::reference_wrapper次を使用して、代わりにを渡すことができますstd::ref

#include <functional>

struct MClass { int totalContents = 0;};

void clickBar(MClass& m) { m.totalContents = 42; }

int main() {   
  MClass mclass;
  auto OnLeftClick = std::bind(clickBar, std::ref(mclass));
  OnLeftClick();
}
于 2013-02-18T11:47:31.593 に答える