2017-11-24 11 views
0

C++初心者はこちら。他のクラスからネットワーク機能にアクセスするにはどうすればいいですか?

リモート・サーバーからコマンドを取得し、テレメトリをリモート・サーバーに戻すロボットを作成するプロジェクトに取り組んで、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クラスを作成しようとしました。これにより、さまざまなタイプのイベント(情報、エラー)を処理するためのコードのカプセル化が可能になり、初期化された '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; 
}; 

私はこのコードをコンパイルしようとしたとき、私はいくつかのエラーを得た:私の新しいクラスは、私は私が渡すことで回避されたと思っている、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のようなものを使用するか、他のクラスからネットワーク機能にアクセスするためのより良い方法がありますか?

ありがとうございます!

答えて

1

これに答えるかオススメとして閉じるかは、投稿して質問者に教えてください。

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はコピー不可能なので、コピーすることはできません。

アスカーがEventReporterインスタンス彼らのコードまたは、彼らは行くために良いことがあり、ソース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 
}; 

です。

+0

私はタイプミスではないと私は誤解していました。メンバー(TcpCom tcpCom)も参照になるというリファレンス(TcpCom&tcpComIn)を渡すと誤解していました。 TcpComは間違いなくEventReporterよりも長生きしているはずなので、この解決策は良いはずです:) – user3878723