【问题标题】:Is boost serialization library is userful? Why doesn't it support "pointer to pointer" serialization?boost序列化库有用吗?为什么它不支持“指针指针”序列化?
【发布时间】:2015-02-13 07:53:24
【问题描述】:

Boost序列化库功能强大,但有些功能我受不了。 例如,Person 是一个类,而我有一群人:

int n = 10;
Person **persons = new Person*[n];
for(int i = 0; i < n; i++) {
    persons[i] = new Person(...);  // whatever Person is.
}

在这里,我想对人物进行序列化,但没有成功。如果我像这样更改代码:

Person *persons[10];
for(int i = 0; i < n; i++) {
    persons[i] = new Person(...);  // whatever Person is.
}

现在它确实起作用了。但在我的项目中,n 不是常数。所以我想知道为什么boost序列化库不支持“指针到指针”序列化。在实际项目中,“指针到指针”很常见,但boost不支持。那么,boost 序列化库有用吗?我不这么认为……

【问题讨论】:

  • In real project, "pointer to pointer" is very common, but boost doesn't support. 实际上是错误的,std::vectorboost::ptr_vector 等处理这个。手动调用 new/delete 应该是不常见的。
  • 是的,boost 支持 STL 库,但是对于时间要求严格的程序,vector/list/set 的性能比 array 差。数据量大,使用STL库查找和遍历会很慢...
  • vector 只是动态数组,没有别的,我不知道,查找和遍历如何会很慢。您使用分析器来解决这个问题?
  • 在 c++ 中,“指向指针的指针”非常不常见。同样相关:stackoverflow.com/questions/27430431/…
  • 这个“向量的性能比数组差”的业务让我想起了 CppCon 小组中的the story Bjarne told

标签: c++ pointers serialization boost


【解决方案1】:

我认为,你应该使用容器,但是,如果分析器说你,那个向量太慢,你可以序列化指针,我不知道它有什么问题。 docs

所以,你可以只使用(也可以在元素之前存储大小)

for (int i = 0; i < n; i++)
{
   ar & persons[i];
}

ar 是存档。

Simple live example

【讨论】:

  • +1 感谢揭穿。使用一些 Boost 序列化,代码仍然可以相当干净:)
【解决方案2】:

序列化:

archive::binary_oarchive oa(ss);
oa << n << boost::serialization::make_array(persons, n);

反序列化:

archive::binary_iarchive ia(ss);
size_t loaded_size;
ia >> loaded_size;
Person** loaded = new Person*[loaded_size];
ia >> boost::serialization::make_array(loaded, loaded_size);

测试:

assert(n == loaded_size);
for (size_t i = 0; i < n; ++i)
    assert(*persons[i] == *loaded[i]);

Live On Coliru

#include <boost/serialization/serialization.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <iostream>
#include <sstream>

using namespace boost;

class Person {
  public:
    Person(int a = 0) : age(a) {}
    bool operator==(const Person &rhs) const { return age == rhs.age; }

  private:
    int age;

    friend class boost::serialization::access;
    template <typename Archive> void serialize(Archive &a, unsigned int) { a &age; }
};

Person** make_persons(size_t n) {
    Person **persons = new Person *[n];
    int i = 10;
    std::generate_n(persons, n, [i]{ return new Person(i); });

    return persons;
}

void free_persons(Person** persons, size_t n) {
    std::for_each(persons, persons+n, [](Person*p){ delete p; });
    delete[] persons;
}

int main() {
    const size_t n = 10;
    Person** persons = make_persons(n);

    std::stringstream ss;

    archive::binary_oarchive oa(ss);
    oa << n << serialization::make_array(persons, n);

    archive::binary_iarchive ia(ss);
    size_t loaded_size;
    ia >> loaded_size;
    Person** loaded = new Person*[loaded_size];
    ia >> serialization::make_array(loaded, loaded_size);

    assert(n == loaded_size);
    for (size_t i = 0; i < n; ++i)
        assert(*persons[i] == *loaded[i]);

    free_persons(loaded, n);
    free_persons(persons, n);
}

【讨论】:

    【解决方案3】:

    C++ 标准没有为 boost 库(或任何其他代码)提供一种方法来了解“T 数组”的大小,这是一个指向T 的指针。这就是为什么 - 例如 - main()argc。因此,如果没有您的帮助,它就无法工作。这就是为什么你最好使用标准容器。您对性能的反对对我来说听起来像是 FUD...存在一两个小的性能问题(C++03 更是如此)-但我怀疑您是否曾经遇到过它们,尤其是在任何重要的代码中都没有。 ..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-12
      • 2016-04-21
      • 2018-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多