如果我必须一次写入一个 char[] 一个字符,或者如果我必须取消引用容器中的所有指针对象并将它们分解为其组成的 POD 部分,首先将它们的大小以字节为单位写入流中,以便序列化boost,那么使用boost似乎没有太大意义。
是的。但是您正在尝试序列化指针。指针应该指向什么char
被序列化为?一定T*
应该序列化动态分配的T
, 不?所以你会期望序列化一个char
unless name
were nullptr
?
或者您是否希望获得序列化的每个角色的完整对象跟踪?
这里的重点是您选择了指向原始类型的原始指针。指针缺少必要的信息。因此,您有责任添加信息。如果你发现tedious,您可以自由地使用 C++ 类型。
顺便请注意,这在 C++03 及更高版本中无论如何都是不合法的:
a.name = (char *)"this is a test";
静态转换来自char const(&)[15]
to char *
会放弃 const 资格。无论如何,你的编译器应该拒绝这段代码。
这是我的看法(使用std::string
):
#include <boost/serialization/string.hpp>
#include <boost/archive/text_oarchive.hpp>
class A {
public:
std::string name;
template <class Archive> void serialize(Archive &ar, unsigned) {
ar & name;
}
};
int main() {
A a { "this is a test" };
boost::archive::text_oarchive os(std::cout);
os << a;
}
顺便说一句,链接的重复问题的标题与您在此处尝试执行的操作完全匹配:Boost C++ 序列化 char * https://stackoverflow.com/questions/5094750/boost-c-serializing-a-char并且接受的答案显示完全相同的解决方案。
If you really坚持认为,你当然可以不顾一切地去研究一些 C 风格的代码:
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <cstring>
#include <cstdlib>
class A {
public:
A(char const* sz = nullptr) : name(sz? strdup(sz) : nullptr) {}
A(A const&) = delete;
A& operator=(A const&) = delete;
~A() { free(name); }
private:
char* name;
template <class Archive> void save(Archive &ar, unsigned) const {
bool have_name = name;
ar & have_name;
if (have_name)
{
size_t len = strlen(name);
ar & len;
ar & boost::serialization::make_binary_object(name, len);
}
}
template <class Archive> void load(Archive &ar, unsigned) {
bool have_name = name;
ar & have_name;
if (!have_name)
{
free(name);
name = nullptr;
} else
{
size_t len = 0;
ar & len;
name = static_cast<char*>(realloc(name, len));
ar & boost::serialization::make_binary_object(name, len);
}
}
friend class boost::serialization::access;
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
int main() {
A a { "this is a test" };
boost::archive::text_oarchive os(std::cout);
os << a;
}
但所有这些给你带来的好处是 6 倍的代码量、残缺的值语义、完全放弃的关注点分离、大量潜在的错误(你有没有想过拥有name==null
and strlen(name)==0
?目前我的实现采用未指定的(实现定义的)行为 http://en.cppreference.com/w/cpp/memory/c/realloc。我将把它作为练习留给读者,在这里提出密封处理)并且......甚至不可读的字符串输出。
是的当然make_array
会给你14 116 104 105 115 32 105 115 32 97 32 116 101 115 116
代替dGhpcyBpcyBhIHRlc3Q=
,但这存储效率极其低下,而且仍然不可读。