【发布时间】:2015-05-13 01:38:56
【问题描述】:
通过以下示例,我尝试学习一些新概念。
- 抽象
- 多态类
- 工厂编程。
- 增强序列化
指针行为方式的细微差别仍然是我正在努力解决的问题。
这是我编写的一个小程序,旨在向您展示我正在努力理解的问题。
当我反序列化下面的多态对象时,我只得到一个从默认构造函数创建的对象。
TodoFactory::retrieveATodo 没有从序列化数据中重新创建对象。这由该函数中“未序列化命令”的输出显示。
这是完整的程序:
#include <string>
#include <bitset>
#include <boost/serialization/string.hpp>
#include <sstream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/export.hpp>
//abstract class
class aTodo{
private:
friend class boost::serialization::access;
protected:
const char _initType;
public:
aTodo():_initType(0x00){};
aTodo(const char type):_initType(type){};
std::string oarchive(){
std::ostringstream archive_stream;
{
boost::archive::text_oarchive archive(archive_stream);
archive << *this;
}
archive_stream.flush();
std::string outbound_data=archive_stream.str();
std::string foutbound_data;
foutbound_data=_initType;
foutbound_data+=outbound_data;
std::cout << "length: " << foutbound_data.length() << std::endl;
return foutbound_data;
}
virtual void Do()=0;
virtual ~aTodo(){};
template<class Archive>
void serialize(Archive & ar, unsigned int version){
ar & _initType;
};
char getInitType(){return _initType;};
};
// include headers that implement a archive in simple text format
class todoExec:public aTodo{
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(
Archive& ar,
unsigned int version
)
{
std::cout << "serialize todoexec" << std::endl;
//base
boost::serialization::base_object<aTodo>(*this);
//derived
ar & _command;
}
std::string _command;
protected:
public:
static const char _TYPE=0x01;
todoExec():aTodo(_TYPE){};
todoExec(std::string command):aTodo(_TYPE){_command=command;};
void Do(){std::cout << "foo" << std::endl;};
virtual ~todoExec(){};
std::string getCommand(){return _command;};
};
class todoFactory{
private:
protected:
public:
std::unique_ptr<aTodo> retrieveAtodo(const std::string & total){
std::cout << "here" << std::endl;
char type=total.at(0);
std::cout << "bitset: " << std::bitset<8>(type) << std::endl;
std::string remainder=total.substr(1);
if(type==0x01){
std::cout << "remainder in retrieve: " << remainder << std::endl;
std::unique_ptr<todoExec> tmp(new todoExec());
std::stringstream archive_stream(remainder);
std::cout << "stream remainder: " << archive_stream.str() << std::endl;
{
boost::archive::text_iarchive archive(archive_stream);
archive >> *tmp;
}
std::cout << "unserialized type: " << std::bitset<8>(tmp->getInitType()) << std::endl;
std::cout << "unserialized command: " << tmp->getCommand() << std::endl;
return std::move(tmp);
}
};
std::unique_ptr<aTodo> createAtodo(char type,std::string command){
if(type==0x01){
std::unique_ptr<todoExec> tmp(new todoExec(command));
return std::move(tmp);
}
};
};
int main(){
char mtype=0x01;
std::string dataToSend = "ls -al /home/ajonen";
std::unique_ptr<todoFactory> tmpTodoFactory; //create factory
std::unique_ptr<aTodo> anExecTodo=tmpTodoFactory->createAtodo(mtype,dataToSend); //create ExecTodo from factory
if(auto* m = dynamic_cast<todoExec*>(anExecTodo.get()))
std::cout << "command to serialize: " << m->getCommand() << std::endl;
//archive
std::string remainder = anExecTodo->oarchive();
//now read in results that are sent back
std::unique_ptr<aTodo> theResult;
theResult=tmpTodoFactory->retrieveAtodo(remainder);
std::cout << "resultant type: " << std::bitset<8>(theResult->getInitType()) <<std::endl;
if(auto* d = dynamic_cast<todoExec*>(theResult.get()))
std::cout << "resultant Command: " << d->getCommand() <<std::endl;
return 0;
}
这是程序输出:
command to serialize: ls -al /home/ajonen
length: 36
here
bitset: 00000001
remainder in retrieve: 22 serialization::archive 12 0 0 1
stream remainder: 22 serialization::archive 12 0 0 1
serialize todoexec
unserialized type: 00000001
unserialized command:
resultant type: 00000001
resultant Command:
我还发现仅对基类 aTodo 调用 serialize 方法。我需要找到一种方法来使那个虚拟化,但它是一个模板函数。这是第一个问题。
【问题讨论】:
标签: c++ serialization boost polymorphism abstract