将成员函数作为参数传递给构造函数 [英] Passing a member function as an argument to a constructor

查看:450
本文介绍了将成员函数作为参数传递给构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个按钮类。我想让按钮类的构造函数接受当按下按钮时它将调用的函数。这很容易,如果按钮类只是从一个类中取一个函数,但按钮的构造函数接受一个函数的目的是,无论什么类的按钮被创建,它将能够存储一个指针的函数

I have a button class. I want the button class's constructor to take the function it will call when the button is pressed. This would be easy if the button class was only taking a function from one class, but the purpose of the button's constructor taking a function is that no matter what class the button is created in it will be able to store a pointer to a function in the class it's created in.

示例:

struct Button {
    Button(void (*functionPtr)()) {
        // Store the function pointer to be called later
    }
};

struct SomeClass {
    void LoadFile();

    SomeClass() {
        Button* temp1 = new Button(&LoadFile); // ???
    }
};

struct AnotherClass {
    void SaveFile();

    SomeClass() {
        Button* temp2 = new Button(&SaveFile); // ???
    }
};

如何使这项工作?

推荐答案

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

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.

这篇关于将成员函数作为参数传递给构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆