Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 序列化:重载加载构造数据:根本没有可访问的构造函数_C++_Boost_New Operator_Boost Serialization - Fatal编程技术网

C++ 序列化:重载加载构造数据:根本没有可访问的构造函数

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设置为等于返回的指针,但这似

因此,我正在使用boost::serialization库,并且我正在尝试解释类的构造方式,因为它没有默认构造函数。这是。在我看来,函数接受
类*t
,然后将其设置为指向新构造的对象。如果我错了,这肯定是我错误的根源

但是,构造我的类的唯一方法是使用另一个class
create()
函数,这意味着我需要偏离示例中的代码(这在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
    -我们只需要找到一个替代放置的新方法,用于非构造函数。非常感谢,经过一周的挫折,你是我的救星!