c++的pub-sub通信(实现无全局变量的多文件间通信)

众所周知:全局变量存在着很多缺点:

全局变量的缺点:

长期占用内存:全局变量生命周期长,程序运行期一直存在,始终占有那块存储区;
难以定位修改:全局变量是公共的,全部函数都可以访问,难以定位全局变量在哪里被修改,加大了调试的难度;
使函数难以理解:使用全局变量的函数,需要关注全局变量的值,增加了理解的难度,增加了耦合性;
初始化顺序:全局变量的初始化顺序不定,如果全局变量之间有依赖,有可能导致某些变量初始化失败呢,引起莫名其妙bug。
污染命名空间:全局变量会污染命名空间,在函数中局部变量会覆盖全局的值,会出现同一个变量名多个值的情况,造成困惑;
增加耦合性:修改全部变量会影响所有用到它的模块,不利于调试;
线程不安全:多线程中多全局变量的修改容易冲突,需要加锁;

尤其是在多文件间的通信中,extern的使用会大大增加程序的耦合性,这在大型项目中是致命的,我们常常使用ROS等工具来解决这一通信问题,在这里给出一个仿照ROS的pub-sub通信机制的Transmission类来 实现无全局变量的多文件间通信。

这里以Bool型和opencv中的图片数据Mat型的数据为例,可以根据所需的数据类型自行调整。

新建Transmission.h,输入:

// Author: gyx
//This is used to define transmission class

#ifndef TRANSMISSION_H
#define TRANSMISSION_H

#include<string>
#include<functional>
#include<map>
#include<list>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/types_c.h>

using std::function;using std::string;using std::map;using std::list;
using cv::Mat;

typedef function<void(bool)>Callback_bool;
typedef function<void(Mat)>Callback_mat;

class Transmission
{
private:
    Transmission() = default;
    map<string,list<Callback_bool>>subscriber_bool;
    map<string,list<Callback_mat>>subscriber_mat;

public:
    static Transmission* getmessage();

    void subscribe_bool(string eventType,Callback_bool callback);
    void subscribe_mat(string eventType,Callback_mat callback);

    void publish_bool(string eventType,bool data);
    void publish_mat(string eventType,Mat src);
};

#endif //TRANSMISSION_H

新建Transmision.cpp,输入:

// Author: gyx
//This is used to establish a pub-sub system

#include<transmission.h>

Transmission* Transmission::getmessage(){
    static Transmission messgae;
    return &messgae;
}

//Transmit bool type data
void Transmission::subscribe_bool(string eventType,Callback_bool callback)
{
    subscriber_bool[eventType].push_back(callback);
}
void Transmission::publish_bool(string eventType,bool data)
{
    for(const auto& callback : subscriber_bool[eventType])
    {
        callback(data);
    } 
}

//Transmit Mat type data
void Transmission::subscribe_mat(string eventType,Callback_mat callback)
{
    subscriber_mat[eventType].push_back(callback);
}
void Transmission::publish_mat(string eventType,Mat src)
{
    for(const auto& callback : subscriber_mat[eventType])
    {
        callback(src);
    } 
}

此时,只需要在需要进行通信的文件中调用Transmission类即可,例:发布图片信息:

Transmission::getmessage()->publish_mat("Capture",CameraScreen);

这里给出Mat型的例子(这是我最近写的一个仿真程序的一部分):

// Author: gyx
//This is used to define the MapWidget class

#ifndef MAPWEIDGIT_H
#define MAPWEIDGIT_H

#include <QObject>
#include<QWidget>
#include<QTimer>
#include<car.h>
#include "transmission.h"

class Subscriber_capture
{
    public:
        CAR data;
        Subscriber_capture(){
        Transmission::getmessage()->subscribe_mat("Capture",[this](Mat src){this->recieve_video_event(src);});
    }
    void recieve_video_event(Mat src)
    {
        data.CameraScreen = src.clone();
    }
};

class MapWidget : public QWidget
{
    Q_OBJECT
protected:
    void  paintEvent(QPaintEvent *event);
    //void keyPressEvent(QKeyEvent *event);
public:
    MapWidget(QWidget *parent = 0);
    QPoint            start_point;
    QPoint            contro_point;

public slots:
    void draw_map();
    void draw_car();
    void start_move();
    void stop_move();

private:
    QImage          *m_img;
    QImage          *c_img;
    QImage          map_img;
    bool                    if_start = 0;
    Subscriber_capture subscriber_capture;
    CAR                     car;
    int  time_count=0;
    QTimer        *timer=new QTimer();
    CAR                 Car;
    // QVector<bool>  switch_vector;
};


#endif

这是图片的信息就已经发布并接受完成了。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值