如何最好地使网络函数从其他类中访问

How to best make network functions accessible from other classes?

本文关键字:其他 访问 函数 何最好 网络      更新时间:2023-10-16

c 新手。

我试图通过研究一个项目来创建一个机器人,该机器人从中获取命令并将遥控器发送回远程服务器来教授自己。

我在机器人上有一个TcpCom类,其中包含套接字连接和公共功能以从服务器发送消息并接收消息:

#ifndef TCPCOM_H
#define TCPCOM_H
#define BOOST_DATE_TIME_NO_LIB
#include <boost/asio.hpp>
#include <boost/interprocess/sync/interprocess_semaphore.hpp>
#include <deque>
#include <mutex>
#include "COM.h"
class TcpCom : public COM
{
    public:
        TcpCom() : io_srv(), tcpSocket(io_srv), remoteHost(""), remotePort(""), connectedToRemoteHost(false), outboundMsgQueue(), outboundMsgQueueMutex(),
        messagesInOutboundMsgQueue(0), incomingMsgQueue(), incomingMsgQueueMutex()
        {}
        int initialize();
        void connectToRemoteHost(const std::string host, const std::string port);
        void disconnectFromRemoteHost();
        bool messagesWaitingInIncomingMsgQueue();
        SoftwareBusMsg getMsgFromIncomingMsgQueue();
        void addMsgToOutboundMsgQueue(SoftwareBusMsg& sbMsg);
        bool isConnected();
    private:
        void writeOutboundMsgToSocket();
        void deserializeHeader(std::string headerStr, MsgHeader& msgHdr);
        void addMessageToIncomingMsgQueue(SoftwareBusMsg& sbMsg);
        void readIncomingMsgHeader(MsgHeader& msgHdr);
        std::string readIncomingMsgData(uint32_t msgDataLength);
        SoftwareBusMsg readMsgFromSocket();
        void incomingMsgThread();
        void outboundMsgThread();
        void startReadAndWriteThreads();
        boost::asio::io_service io_srv;
        boost::asio::ip::tcp::socket tcpSocket;
        std::string remoteHost;
        std::string remotePort;
        bool connectedToRemoteHost;
        std::deque<std::string> outboundMsgQueue;
        std::mutex outboundMsgQueueMutex;
        boost::interprocess::interprocess_semaphore messagesInOutboundMsgQueue;
        std::deque<SoftwareBusMsg> incomingMsgQueue;
        std::mutex incomingMsgQueueMutex;
        //boost::interprocess::interprocess_semaphore messagesInIncomingMsgQueue;
};
#endif

我希望其他类别(例如负责电动机控制的类别)具有将消息发送到服务器进行遥测/错误报告的能力。我可能在这里错了,但是直接将TcpCom类的实例传递给需要将消息发送到服务器的每个类的设计似乎很差。

相反,我尝试创建一个具有私人成员的EventReporter类,该类是对TcpCom类的引用。这将允许封装用于处理不同类型的事件的代码(信息,错误),我可以将初始化的" EventReporter"对象传递给所有需要它的事件。

#include "TcpCom.hpp"
class EventReporter
{
    public:
        EventReporter(TcpCom& tcpComIn) : tcpCom(tcpComIn)
        {}
        //Will contain call to tcpCom.addMsgToOutboundMsgQueue()
        void reportEvent(std::string eventType, std::string message);
    private:
        TcpCom tcpCom;
};

当我尝试编译此代码时,我遇到了一些错误:

error: use of deleted function 'TcpCom::TcpCom(const TcpCom&)'
error: use of deleted function 'boost::asio::io_service(const boost::asio::io_service&)'

看来我的新课程将试图制作TcpCom的副本,我认为我通过参考来避免了它。

我应该使用诸如unique_ptr之类的东西避免复制TcpCom,还是有更好的方法使网络功能可以从其他类中访问?

谢谢!

是抛弃是回答还是打字,所以我会发布并让问题的询问告诉我。

class EventReporter
{
    public:
        EventReporter(TcpCom& tcpComIn) : tcpCom(tcpComIn)
        {}
        //Will contain call to tcpCom.addMsgToOutboundMsgQueue()
        void reportEvent(std::string eventType, std::string message);
    private:
        TcpCom tcpCom; //<- this is not a reference
};

TcpCom tcpCom;定义了 TcpCom的实例,而不是对 TcpCom的引用,如问候者所说的那样,因此在成员初始化列表中的 tcpCom(tcpComIn)(顺便说一句,在使用列表上,对他们来说很好。许多认为自己是的C 程序员不再学习似乎不知道它们存在)执行他们试图避免通过参数列表中的参考来避免的副本。

错误消息是由成员产生的(至少是std :: mutex。静音的多个副本是不好的)TcpCom是不可复制的,因此即使您愿意,也无法复制一个。

简单的解决方案是

class EventReporter
{
    public:
        EventReporter(TcpCom& tcpComIn) : tcpCom(tcpComIn)
        {}
        //Will contain call to tcpCom.addMsgToOutboundMsgQueue()
        void reportEvent(std::string eventType, std::string message);
    private:
        TcpCom & tcpCom; //<- change made here
};

除非询问器具有其他不可复制的对象,否则在其代码或 EventReporter实例中的其他位置也可以超过源TcpCom,它们应该很好。