且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

将成员函数作为参数传递给构造函数

更新时间:2022-06-27 02:41:08

尽管看起来很相似,指针函数和指针成员函数实际上是完全不同的野兽。

A pointer-to-function and a pointer-to-member-function, despite seeming pretty similar, are actually entirely different beasts.

void(* functionPtr)()是一个指向不带参数并返回void的函数的指针。 & AnotherClass :: SaveFile 是指向 AnotherClass 成员函数的指针。它的类型是 void(AnotherClass :: *)()。请注意,类名是类型的一部分,因此您不能简单地将指针到成员函数存储到任意类。此外,要调用指针到成员函数,你需要一个实例指针 - 你必须以某种方式存储,但那些也将有不同的类型!

void (*functionPtr)() is a pointer to a function that takes no arguments and returns void. &AnotherClass::SaveFile is a pointer to a member function of AnotherClass... its type is void (AnotherClass::*)(). Notice that the class name is part of the type, so you can't simply store a pointer-to-member-function to an arbitrary class. Furthermore, to call a pointer-to-member-function, you need an instance pointer - you'd have to store that somehow, but those would have different types too!

在C ++ 11中可以做的是使用type-erasure:

What you could do instead in C++11 is use type-erasure:

std::function<void()> callback;

并为其指定一个任意的可调用:

And assign an arbitrary callable to it:

template <typename F>
Button(F cb) 
: callback(cb)
{ }

然后,您可以使用 std :: bind 创建按钮:

And then you could create a button using std::bind:

Button* temp1 = new Button(std::bind(&OtherClass::LoadFile, this));
Button* temp2 = new Button(std::bind(&AnotherClass::SaveFile, this));



现在 temp1-> callback()实际上会调用 OtherClass 的实例调用 LoadFile()。这是你想要的。而且,我们仍然可以使用***函数:

Now temp1->callback() will actually call LoadFile() on the instance of OtherClass that it was constructed with. Which is what you wanted. And, we can still use free functions:

void whatever();
Button* temp3 = new Button(whatever);

插入关于使用原始指针和 new 并偏好 unique_ptr

Insert the usual caveats about using raw pointers and new and preferring unique_ptr.