-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()that的函数时clickBar(), 的值totalContents不会变为 0(totalContents 值由 MClass 的其他函数递增)。

我在这里做错了吗?

4

2 回答 2

1

调用中的this参数std::bind实际上是函数的第一个参数。对于成员函数,这必须是该函数所属的类的实例,因为所有成员函数都有一个隐藏的第一个参数,即this指针。

因此,要使您的代码正常工作, 的第一个参数必须VScrollbar::Scrolldown是类的实例,而VScrollbar不是this. MClass像这样:

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

对于第二次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 回答