【发布时间】:2020-10-02 23:03:09
【问题描述】:
我正在使用 boost 进行数据序列化。
这就是类的结构。
1) 我有一个 Stage 课程 该类保存director类的矢量数据
class Stage
{
public:
std::vector<Director> directors;
void AddDirector(Director dir) { directors.push_back(dir); }
int GetDirectorSize() { return directors.size(); }
Director* GetDirector(int number) { return &directors[number]; }
private:
friend class boost::serialization::access;
template<typename Archive>
void save(Archive& ar, const unsigned int version) const {
ar & directors;
}
template<typename Archive>
void load(Archive& ar, const unsigned int version) {
ar & directors;
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
2) 这是导演类 该类保存通道类的弱指针向量数据。
class Director
{
public:
std::string stdstrName;
std::vector<std::weak_ptr<Channel>> channels;
Director() { stdstrName = "NO_NAME"; }
void SetName(std::string name) { stdstrName = name; }
std::string GetName() { return stdstrName; }
void AddChannel(std::weak_ptr<Channel> chn) { channels.push_back(chn); }
std::shared_ptr<Channel> GetChannel(int number) { return channels[number].lock(); }
int GetChannelSize() {return channels.size();}
std::string GetChannelType( int number){
if (std::shared_ptr<Channel> chn = channels[number].lock())
return chn->GetChannelType();
}
private:
friend class boost::serialization::access;
template<typename Archive>
void save(Archive& ar, const unsigned int version) const {
ar & stdstrName & channels;
}
template<typename Archive>
void load(Archive& ar, const unsigned int version) {
ar & stdstrName & channels;
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
3) 这是通道类
Channel 类需要知道创建它的容器以及 将其存储为 Weak_pointer 的导向器
1) 这个类拥有一个指向 Director 对象的指针。
2) 这个类拥有一个指向 Container 对象的指针。
class Container;
class Director;
class Channel
{
public:
Director* dir;
Container* cont;
std::string stdstrChannelType;
Channel() { stdstrChannelType = "NO_TYPE"; }
Channel(std::string type): stdstrChannelType(type){ }
void SetDirector(Director* director);
void SetContainer(Container* container);
std::string GetChannelType() { return stdstrChannelType;}
Director* GetDirector() { return dir; }
private:
friend class boost::serialization::access;
template<typename Archive>
void save(Archive& ar, const unsigned int version) const {
ar & dir & cont & stdstrChannelType;
}
template<typename Archive>
void load(Archive& ar, const unsigned int version) {
ar & dir & cont & stdstrChannelType;
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
/////////////////////////////////////// /////////////////////////////////////////p>
#include "Channel.h"
#include <vector>
class PositionChannel : public Channel
{
public:
std::vector<int> keyframes;
PositionChannel() : Channel("POSITION") , keyframes( { 1 , 2, 3 }) { }
private:
friend class boost::serialization::access;
typedef Channel _Super;
template<typename Archive>
void save(Archive& ar, const unsigned int version) const {
ar & boost::serialization::base_object<_Super>(*this);
ar & keyframes;
}
template<typename Archive>
void load(Archive& ar, const unsigned int version) {
ar & keyframes;
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
4) 这是容器类
1) 这是创建 Channel 并保存为 Shared_pointer 的位置。
2) 相同的通道也作为Weak_Pointer保存在Director类中
class Container
{
public:
std::string stdstrName;
std::vector<std::shared_ptr<Channel>> channel;
Container() { stdstrName = "cont"; };
void AddChannel(std::shared_ptr<Channel> chn)
{
channel.push_back(chn);
Director* dir = chn->GetDirector(); // Add the channel to director also
dir->AddChannel(chn);
}
private:
friend class boost::serialization::access;
template<typename Archive>
void save(Archive& ar, const unsigned int version) const {
ar & stdstrName & channel;
}
template<typename Archive>
void load(Archive& ar, const unsigned int version) {
ar & stdstrName & channel;
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
现在当我序列化我的数据而不是序列化它时,Director 无法序列化weak_pointer。
Stage stage;
Director dir;
Container cont;
dir.SetName("MAIN");
stage.AddDirector(dir); // Add director to stage
std::shared_ptr<PositionChannel> chn = std::make_shared<PositionChannel>(PositionChannel()); // create a position channel
chn->SetDirector(&dir); // Link the director to channel
chn->SetContainer(&cont); // Link the container to the channel
cont.AddChannel(chn); // add the channel to the container
std::cout << dir.GetChannelSize() << std::endl; // this gives a value of 1 which is correct
std::ofstream ofs("D://abc.dat");
{
boost::archive::text_oarchive oa(ofs);
// write class instance to archive
oa << stage << cont; // since director is a data element of stage so it should get serialized
}
Stage stage1;
Container cont1;
{
// create and open an archive for input
std::ifstream ifs("D://abc.dat");
boost::archive::text_iarchive ia(ifs);
// read class state from archive
ia >> stage1 >> cont1;
}
std::cout << stage1.GetDirectorSize(); // stage has got the director
Director* dir1 = stage1.GetDirector(0);
std::cout << dir1->GetName(); // the director has the correct name
std::cout << dir1->GetChannelSize(); // it should show 1 as the channel size but i am getting 0
【问题讨论】:
-
问题是什么? “Director 无法序列化weak_pointer”——这是否意味着它无法编译?它做你所期望的吗?会发生什么?
-
@sehe 我把这个问题复杂化了,请看看我的新问题,stackoverflow.com/questions/62367775/…
-
我同意你把它复杂化了。不是问题,而是代码。也许您应该使用简单的拥有对象,并使用单独的集合/映射建立关系。我觉得你可以在没有单个共享指针或循环依赖的情况下对此进行建模。
标签: c++ serialization boost c++14