【发布时间】: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. 调用aTodoInherited.writeRead()。您是在建议我在另一个处理发送和接收的类中创建一些静态方法,这样不会那么混乱?
-
在我写这篇文章的时候,我明白你的意思了。我需要谷歌单一责任原则......
-
我建议你有一些其他的类来管理服务器连接和读取/写入它。没有理由让它是静态的。这从这个特定的类中删除了这个代码,清理它并使其更容易推理,这使得发现错误更容易,而且如果你有其他类,你可以更容易地重用代码。这个类中唯一需要的就是 serialise 方法。查看单一职责原则,它将提高您的代码设计技能。
标签: c++ sockets serialization boost polymorphism