对象以序列化的形式是否有效?c++ /产业/序列化
Is an object valid in serialized form? c++/inheritance/serialization
我问这个问题,因为即使它似乎工作,我觉得它不应该。目标是使一组对象保持活动状态,并对它们进行一般访问。这是我现在的文件:
接受基指针访问:
struct base { virtual void tick() = 0; }; //ptr access
具有从它继承的不同类型:
struct :public base
{
void tick() { cout << "im type 1" << endl; }
}type1;
struct :public base
{
void tick() { cout << "im type 2" << endl; }
}type2;
然后是一个容器类,该容器类应该能够存储任意数量的这些序列化对象:
class control
{
struct xtype //struct for organizing objects
{
vector<char>charbuf; //serialized object
}xtype_template;
vector<xtype>xtype_vec;
public:
template<typename T> base* tell_to(T &input) //take object, return (base*)
{
xtype_template.charbuf.resize(sizeof(input));
memcpy(xtype_template.charbuf.data(), (char*)&input, sizeof(input));
xtype_vec.push_back(xtype_template); //push back with template after filling
return (base*)xtype_vec[xtype_vec.size() - 1].charbuf.data(); //pointer to data
}
}xcontainer; //container object
然后调用:
auto ptr = controller.tell_to(type1); //becomes base*
auto ptr2 = controller.tell_to(type2);
您可以访问静态大小的序列化对象,以及它的状态,通过执行:
ptr->tick(); //which will output "im type 1" to console
ptr2->tick() //"im type 2"
但是这合法吗?这些序列化的版本有实际的类型吗?直接使用基指针访问序列化对象是非法的还是错误的?
最接近的答案:由于is_trivially_copyable的返回值显示为false,对象在获得基继承后可能不安全。
Follow up:这种方法似乎是有效的,并且摆弄is_trivially_copyable
,似乎表明使对象继承方法使其不安全。然而,基本方法并不使其不安全,这使我怀疑安全性是否仅适用于在系统之间导出,保存到文件或通过网络传输。也许检查只是假设虚拟引用使它们不安全?
后续2:如果字符保持在内存中的相同位置,那么如何访问它们是否重要?我敢打赌,这种方法唯一真正的问题是,如果存储的对象具有在存储后会改变其大小的元素。
你这样做是违法的。当对象为TriviallyCopyable
时,只能将对象memcpy
作为char
的数组。而你的对象不是,因为它有虚函数。
class xtype
{
std::unique_ptr<base> ptr;
public:
template<typename T> base* serial_acc(T &input) //take object, return (base*)
{
static_assert(std::is_base_of<base, T>::value, "Please use proper type");
ptr = std::make_unique<base>(input);
return ptr;
}
} xcontainer;
用户Andy Prowl给出的工作示例
#include <vector>
#include <memory>
#include <iostream>
using namespace std;
struct base
{
virtual void tick() = 0;
};
struct type1 : base
{
virtual void tick() override { cout << "im type 1"<<endl; }
};
struct type2 : base
{
virtual void tick() override { cout << "im type 2" << endl; }
};
struct controller
{
vector<unique_ptr<base>> objects;
void cycle_tick(){ for (auto const& ptr : objects)ptr->tick();}
void add_object(unique_ptr<base> obj){ objects.emplace_back(move(obj));}
};
int main()
{
auto t1 = unique_ptr<type1>(new type1);
auto t2 = unique_ptr<type2>(new type2);
controller ctrl_object;
c.add_object(move(t1));
c.add_object(move(t2));
ctrl_object.cycle();
}
相关文章:
- 如何在C++中序列化结构数据
- 序列化,没有库的整数,得到奇怪的结果
- 如何知道QDataStream不能反序列化某些内容
- 如何使用Python从C++中读取谷物序列化数据
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 带有Protobuf序列化的C++Hazelcast:字符串不是UTF-8格式的
- 自定义对象的dlib序列化在gcc中失败
- C++boost序列化多态性问题
- 增强基于 XML class_id的反序列化
- 提升反序列化对象具有 nan 或 -nan 值
- 在 cpp 中的平面缓冲区中序列化对象
- 每次进行继承时都需要提升::序列化::base_object吗?
- 如何在 c++ 非托管代码中反序列化 byte[] 的 json 字符串?
- 提升序列化 1:73 的向后兼容性问题
- 将 boost 序列化对象的 asio::streambuf 表示转换为 Beast 的 DynamicBody req.body()
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 如何反序列化数组?
- 如何使用提升序列化?
- 序列化多晶型接口
- FlatBuffers/Protobuf 中是否有支持任意 24 位有符号整数定义的可移植二进制序列化架构?