【问题标题】:send and receive serialized classes from a base class从基类发送和接收序列化类
【发布时间】:2015-12-20 04:29:10
【问题描述】:

我的目标是创建一个具有以下方法的基类: 1.序列化并发送到服务器 2. 从服务器序列化字节读回 3. 从序列化字节重新创建自己

这是为了避免第二个类会为您的类序列化、发送、读回和重新创建结果。

影响我将来可能需要的每个继承类的通信构建。任何继承类都不需要创建发送/接收方法,因为基类已经具有该方法。他们只需要 void serialize(Ar &, unsigned) 方法就可以让 boost 进行序列化。

我的问题是在下面的保存方法中,archive << this; 会根据指针保存并在子类而不是基类上调用存档吗?

换一种说法:我是否需要在继承自 aTodo.h 的类上编写新的 save()load() 方法?这是我想要避免的。

我创建的基类叫做aTodo.h:

#ifndef ATODO_H
#define ATODO_H
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/unique_ptr.hpp>

#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include "protocolBaseServer.h"
#include "memory.h"
class aTodo{
  public:
   virtual ~aTodo(){};
   virtual void Do()=0;

   //used for a client to send and then receive result back
   std::unique_ptr<aTodo>  WriteRead(std::string ip, int port){

    protocolBaseServer protoConnection(ip, port);
    std::string objToSendStr = this->save(); //save to a string
    protoConnection.DoWrite(objToSendStr);//send string off to server; server does some work
    protoConnection.DoRead();  //read back in the result from the server to a string in object protoConnection
    std::string returnedObjectStr= protoConnection.getTotalMessage(); //save the read bytes to a string
    std::unique_ptr<aTodo> objectReturned=this->load(returnedObjectStr);
    return objectReturned;
   }

   private:

   friend class boost::serialization::access;
   template  <class Ar>
   void serialize(Ar &, unsigned){};//every class that inherits from aTodo must have a serialize function

//save pointer to this to a string
   std::string save(){
         std::string out;
         {
            boost::iostreams::stream<boost::iostreams::back_insert_device<std::string>>os(out);
            boost::archive::text_oarchive archive(os);

            archive << this;
         }
         return out;
   }
//write aTodo pointer from string
   std::unique_ptr<aTodo> load(std::string const &s ){
         std::unique_ptr<aTodo> p;
         {
            boost::iostreams::stream<boost::iostreams::array_source> is(boost::iostreams::array_source{s.data(),s.size()});
            boost::archive::text_iarchive archive(is);
            archive >> p;

         }
         return std::move(p);

  }


};
#endif

【问题讨论】:

  • 我个人觉得这不应该在基类中。它违反了单一责任原则。该代码应该在其他负责保存和加载服务器对象的类中。但这不是你问的。
  • @DominicMcDonnell 我有点同意。我不介意它在那里,但它会导致更糟糕的代码。另外,真正的问题可以通过简单的尝试来回答:)
  • @DominicMcDonnell 为什么这样不那么粗俗。我认为 1. 创建 aTodoInherited 对我来说会更容易。 2. 调用aTod​​oInherited.writeRead()。您是在建议我在另一个处理发送和接收的类中创建一些静态方法,这样不会那么混乱?
  • 在我写这篇文章的时候,我明白你的意思了。我需要谷歌单一责任原则......
  • 我建议你有一些其他的类来管理服务器连接和读取/写入它。没有理由让它是静态的。这从这个特定的类中删除了这个代码,清理它并使其更容易推理,这使得发现错误更容易,而且如果你有其他类,你可以更容易地重用代码。这个类中唯一需要的就是 serialise 方法。查看单一职责原则,它将提高您的代码设计技能。

标签: c++ sockets serialization boost polymorphism


【解决方案1】:

你很好。只要你通过指针序列化(你这样做) 还有types are exported,你很好。

当然,API 设计存在一些值得注意的问题(load 应该是静态的;getTotalMessage 可能不应该与 DoRead 分开等)

【讨论】:

  • 非常感谢你。你已经回答了很多我的提升问题。
  • 您如何看待 load() 写入“this”指针而不是另一个指针?
  • @user249806 我想你忘记了你不能。它将如何动态构造正确的子类型?
  • 你是对的。我将其更改为静态。感谢您的建议和解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-08
  • 1970-01-01
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多