C++ C+;中按钮的简单信号+;

C++ C+;中按钮的简单信号+;,c++,function-pointers,signals-slots,C++,Function Pointers,Signals Slots,我一直在研究一些信号/插槽实现,毫无例外,它们都非常复杂,有些甚至依赖于MOC和额外的代码生成,比如Qt 我意识到存在威胁安全等问题,但对于一个简单的单线程场景,使用简单的方法是否有问题,比如: typedef void (*fPtr)(); class GenericButton { public: GenericButton() : funcitonToCall(nullptr) {} void setTarget(fPtr target) { funcit

我一直在研究一些信号/插槽实现,毫无例外,它们都非常复杂,有些甚至依赖于MOC和额外的代码生成,比如Qt

我意识到存在威胁安全等问题,但对于一个简单的单线程场景,使用简单的方法是否有问题,比如:

typedef void (*fPtr)();

class GenericButton
{
public:
    GenericButton() : funcitonToCall(nullptr) {}
    void setTarget(fPtr target) {
        funcitonToCall = target;
    }

    void pressButton() {
        if (funcitonToCall) funcitonToCall();
    }

private:
    fPtr funcitonToCall;
};

void doSomething(){
    std::cout << "doing something..." << std::endl;
}

void doSomethingElse(){
    std::cout << "doing something else..." << std::endl;
}

int main(){
    GenericButton myButton;
    myButton.setTarget(doSomething);
    myButton.pressButton();
    myButton.setTarget(doSomethingElse);
    myButton.pressButton();
}
typedef void(*fPtr)();
类GenericButton
{
公众:
GenericButton():functionToCall(nullptr){}
无效设置目标(fPtr目标){
functionToCall=目标;
}
无效按按钮(){
if(functionToCall)functionToCall();
}
私人:
fPtr functiontocall;
};
无效剂量测定法(){

std::cout这是一个非常合理的解决方案,但不要将自己局限于函数指针。使用
std::function
可以绑定对象、调用对象上的成员函数、使用lambda并在有意义的地方仍然使用函数指针。示例:

#include <iostream>
#include <functional>

using namespace std::placeholders;


class GenericButton
{
public:
    typedef std::function<void()> fPtr;
    GenericButton() : funcitonToCall(nullptr) {}
    void setTarget(fPtr target) {
        funcitonToCall = target;
    }

    void pressButton() {
        if (funcitonToCall) funcitonToCall();
    }

private:
    fPtr funcitonToCall;
};

struct foo {
    void doSomething() const {
        std::cout << "doing something in a foo..." << std::endl;
    }

    static void alternative(int i) {
        std::cout << "And another, i=" << i << "\n";
    }
};

void doSomethingElse() {
    std::cout << "doing something else..." << std::endl;
}

int main() {
    GenericButton myButton;
    foo f;
    myButton.setTarget(std::bind(&foo::doSomething, &f));
    myButton.pressButton();
    myButton.setTarget(doSomethingElse);
    myButton.pressButton();
    myButton.setTarget(std::bind(foo::alternative, 666));
    myButton.pressButton();
    myButton.setTarget([](){ std::cout << "Lambda!\n"; });
    myButton.pressButton();
}
#包括
#包括
使用名称空间std::占位符;
类GenericButton
{
公众:
typedef std::函数fPtr;
GenericButton():functionToCall(nullptr){}
无效设置目标(fPtr目标){
functionToCall=目标;
}
无效按按钮(){
if(functionToCall)functionToCall();
}
私人:
fPtr functiontocall;
};
结构foo{
void doSomething()常量{

std::我可以使用
std::function
std::bind
(或boost替代方案)吗与其说是函数指针,不如说是函数指针。我想是的,我对c++11还是个新手。这很好,但我想问一下,与其他成千上万个过于复杂的LOC信号/插槽实现相比,使用这种简单方法的缺点。@ddriver-我略过了我的观点-标准工具比n复杂的东西,比如Qt的信号/插槽机制。你可以跳过数千个LOC工具,把所有繁重的工作留给标准的、可移植的、仅仅是一个函数指针就可以使用的东西。因此,是的,简化的机制很有意义,但原始函数指针并不是真正的工具。我主要使用的是原始函数指针离子指针,因为最初我问C和C++,C都被编辑出来了,可能是因为我使用了一个类而不是一个Stutt。C++中的11个特性在C中是不可用的:无论如何,<代码> STD::BIN < /C> >对于使用这个签名的任何函数来说都是有用的,包括一个特定实例的类成员方法。