gpt4 book ai didi

c++ - 如何最好地使其他类可以访问网络功能?

转载 作者:行者123 更新时间:2023-11-28 04:54:38 27 4
gpt4 key购买 nike

这里是 C++ 新手。

我正在尝试通过一个项目自学 C++,以创建一个从远程服务器获取命令并将遥测数据发送回远程服务器的机器人。

我在 Robot 上有一个 TcpCom 类,它包含套接字连接和用于发送消息和从服务器接收消息的公共(public)函数:

#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 类,它有一个私有(private)成员,该成员是对 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&)'

看起来我的新类(class)将尝试制作 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 的一个实例,而不是 Asker 所说的对 TcpCom 的引用,所以 成员初始化器列表中的 tcpCom(tcpComIn)(顺便说一下,他们使用列表很好。许多认为他们不再学习的 C++ 程序员似乎不知道它们的存在)执行复制它们是试图通过参数列表中的引用传递来避免。

错误消息是由于 TcpCom 的成员(至少是 std::mutex。互斥量的多个拷贝会很糟糕)不可复制,所以即使你想要。

简单的解决方案是

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
};

除非 Asker 有其他不可复制的对象也被复制到他们代码中的其他地方,或者 EventReporter 实例可以比源 TcpCom 活得更久,否则他们应该很高兴。

关于c++ - 如何最好地使其他类可以访问网络功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47466756/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com