C++ 序列化:重载加载构造数据:根本没有可访问的构造函数
因此,我正在使用boost::serialization库,并且我正在尝试解释类的构造方式,因为它没有默认构造函数。这是。在我看来,函数接受C++ 序列化:重载加载构造数据:根本没有可访问的构造函数,c++,boost,new-operator,boost-serialization,C++,Boost,New Operator,Boost Serialization,因此,我正在使用boost::serialization库,并且我正在尝试解释类的构造方式,因为它没有默认构造函数。这是。在我看来,函数接受类*t,然后将其设置为指向新构造的对象。如果我错了,这肯定是我错误的根源 但是,构造我的类的唯一方法是使用另一个classcreate()函数,这意味着我需要偏离示例中的代码(这在boost::serialization命名空间中说明):::new(t)my_class(attribute) 我试图简单地调用create函数并将t设置为等于返回的指针,但这似
类*t
,然后将其设置为指向新构造的对象。如果我错了,这肯定是我错误的根源
但是,构造我的类的唯一方法是使用另一个classcreate()
函数,这意味着我需要偏离示例中的代码(这在boost::serialization命名空间中说明):::new(t)my_class(attribute)代码>
我试图简单地调用create函数并将t
设置为等于返回的指针,但这似乎不起作用,因为就在load\u construct\u data函数之后,在序列化函数中,给定的myClass&
与我设置的“t”不同
我该怎么做::new(t)正在这样做使用create函数创建的对象会一直跟随到serialize/other函数中?您的问题中提到的构造(new(t)my_class(attribute)
)称为“placement new”。它的工作方式是
t
必须已经指向分配的内存区域(默认情况下,placement new不进行分配)
在该内存位置构造了my_类的一个实例
但是,因为在您的情况下不能使用构造函数,所以使用任何形式的new
都是不可能的。但还有一种选择(某种程度上)
由于placement new几乎只覆盖块内存,因此我们可以使用一个常规函数,对已经构造的对象执行相同的操作。这样的函数是memcpy
:
void * memcpy ( void * destination, const void * source, size_t num );
memcpy
所做的全部工作就是将num
字节从source
指向的内存复制到destination
指向的内存
假设您从load\u construct\u data
my_class obj = other_class::create();
然后我们可以使用memcpy
函数通过t
将obj
处的值“移动”到内存引用中:
memcpy((void*)t, (void*)(&obj), sizeof(obj));
虽然有一些细节是关于这个如何与你的特定类一起工作的,比如一个稍微明智的拷贝是否“足够好”,但这是我对你所问问题的最好回答。我看到的一个问题是,如果析构函数释放资源,那么副本可能会变得无效
为了解决销毁过程中可能出现的问题,您可以编写自己的深度复制函数:
void deepCopy( my_class * destination, const my_class * source );
您调用它而不是memcpy
注意:如果我在这里误入歧途,请告诉我。我目前没有测试代码的机器。在没有默认构造函数的情况下,使用load\u construct\u data和save\u construct data实际上允许使用共享的\u ptr实例。在我看来,没有必要玩弄memcpy和原始指针。因此,您可以执行如下操作
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/string.hpp>
#include <memory>
class MyClass {
public:
explicit MyClass(std::string const &str) : m_str(str) {}
MyClass() = delete;
std::string str() const
{
return m_str;
}
private:
std::string m_str;
};
namespace boost { namespace serialization {
template<class Archive>
void serialize(Archive &ar,
MyClass const & myClass,
unsigned int const)
{
auto str = myClass.str();
ar & str;
}
template<class Archive>
void save_construct_data(Archive &ar,
MyClass const * myClass,
unsigned int const)
{
auto str = myClass->str();
ar << str;
}
template<class Archive>
void load_construct_data(Archive &ar,
MyClass * myClass,
unsigned int const)
{
std::string archived;
ar >> archived;
::new(myClass)MyClass(MyClass(archived));
}
}
}
int main(int argc, const char * argv[]) {
std::shared_ptr<MyClass> myClass(new MyClass("hello!"));
std::stringstream os;
::boost::archive::text_oarchive oa(os);
oa << myClass;
std::shared_ptr<MyClass> myClassB;
std::stringstream is;
is.str(os.str());
::boost::archive::text_iarchive ia(is);
ia >> myClassB;
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
类MyClass{
公众:
显式MyClass(std::string const&str):m_str(str){}
MyClass()=删除;
std::string str()常量
{
返回m_str;
}
私人:
std::字符串m_str;
};
命名空间boost{命名空间序列化{
模板
作废序列化(存档和应收账款),
MyClass常量和MyClass,
无符号整数常量)
{
auto str=myClass.str();
ar&str;
}
模板
作废保存构造数据(存档和应收账款),
MyClass常量*MyClass,
无符号整数常量)
{
自动str=myClass->str();
ar>存档;
::新建(myClass)myClass(myClass(存档));
}
}
}
int main(int argc,const char*argv[]{
std::shared_ptr myClass(新的myClass(“hello!”);
std::stringstream操作系统;
:boost::archive::text_oarchive oa(操作系统);
oa>myClassB;
返回0;
}
我认为你的意思是熟练,而不是足够,但你不需要说这些-这是从标签中暗示出来的。此外,这个问题似乎并不是围绕着boost
-我们只需要找到一个替代放置的新方法,用于非构造函数。非常感谢,经过一周的挫折,你是我的救星!