从零开始实现信号槽机制:一

本文探讨了如何从头实现信号槽机制,以解决组件间通信的解耦问题。通过逐步改进,从静态成员函数的回调到非静态成员函数的回调,最终引入信号和槽的概念,实现更灵活的连接与断开。文章通过实例展示了这一过程,并预告将对比Qt的信号槽实现及其灵活性。
摘要由CSDN通过智能技术生成

我们从一个具体的问题入手:

现在有一堆按钮,以及一堆电器,按钮对它需要控制的对象一无所知,电器也不知道它们开关的具体类型,它们之间的关系可能是一对多,也可能是多对一,并且需要支持动态添加和删除,应该如何设计这个结构?

这里有个形象的图:



基于静态成员函数的回调

--------------------------------------------------------------------------------

为了实现组件间的控制,我们很容易想到“回调函数”,对于C++开发者,我们肯定不希望一个类自身的处理函数存在于类外,但是类成员函数中被自动添加的隐形this形参造成了函数指针调用的不匹配,于是我们想到了使用static成员函数:

// 被调类
class Tv
{
public:
    static void onBtnClicked(bool b)
    {
        if ( b == true )
            cout << "Tv is being turned on.";
        else
            cout << "Tv is being turned off.";
    }
};

// 还有其他可能被调用的对象
// class Lamp...
// class Laptop...

typedef void (*PF)(bool);
class Button
{
public:
    //主调函数
    void click(PF p, bool b)
    {
        p(b);
    }
};

int main()
{
    PF p = &Tv::onBtnClicked;
    Button btn;
    btn.click(p, true);
    return 0;
}

这样我们就可以动态地为Button赋上它需要调用那个函数并执行。但缺点也是显而易见的——被调函数作为静态函数不能访问非静态成员与函数,Button触发的结果对于每一个Tv对象都是一样的,这显然不是我们想要的。因此,我们想到了在Button中动态地传入被调对象的指针,这样,通过这个指针我们就可以调用该对象的非静态成员函数了。由于Button还需要控制其他设备,我们很自然地想到使用模板:


基于非静态成员函数的回调

--------------------------------------------------------------------------------

//被调类
class Tv
{
public:
    Tv(int t1, int t2) : bootTime(t1), offTime(t2){}
    //被调函数
    void onBtnClicked(bool b)
    {
        if ( b == true )
            cout << "Tv is being turned on. bootTime is " << bootTime;
        else
            cout << "Tv is being turned off. offTime is " << offTime;
    }
private:
    int bootTime;
    int offTime;
};

// 还有其他可能被 Button 类控制的被调类
class Lamp
{
public:
    void onBtnClicked()
    {
        cout << "This Lamp is control by voice";
    }
};

// class Laptop...

// 主调类
template<typename Tobject, typename Tparam>
class Button
{
    typedef void (Tobject::*Tfunc)(T
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值