我使用这个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()
的函数时,
totalContents
的值不会更改为0(totalContents值会被MClass的其他函数递增)。
答案 0 :(得分: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
函数访问。
答案 1 :(得分: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();
}