1

我有一堆结构可以从各种文件中读取,以避免为每个文件定义重复,我考虑过使用以下内容operator>>operator<<

#include <fstream>

#pragma pack(push, 1)

template<typename Derived>
struct Base
{
    friend std::istream& operator>>(std::istream& stream, Base& base)
    {
        return stream.read(reinterpret_cast<char*>(&base), sizeof(Derived));
    }
    friend std::ostream& operator<<(std::ostream& stream, Base const& base)
    {
        return stream.write(reinterpret_cast<char const*>(&base), sizeof(Derived));
    }
};

struct Foo : public Base<Foo>
{
    int32_t i;
    int8_t j, k, l;
    uint16_t m;
};

struct Bar : public Base<Bar>
{
    int32_t i;
    uint16_t m;
};

#pragma pack(pop)

int main()
{
    Foo foo;
    Bar bar;

    std::ifstream("foobarout", std::ios::binary) >> foo >> bar;
    std::ofstream("foobarout", std::ios::binary) << foo << bar;
}

是使用指向明确定义的基类的指针来读取/复制像上面这样的简单 POD 对象(至少在我正在运行的单个平台的范围内,我意识到这不一定是可移植的),还是我在踩在薄冰上?

4

2 回答 2

3

我会说这不是一个好的解决方案。

它会起作用,但从客户端实现者的角度来看,看起来您将定义这些运算符,但随后它们取决于处于二进制模式的流(这不是明确的或您的界面建议的 - 不要那样做)它需要使用 reinterpret_cast (也不要这样做)。您对 POD 类型的限制也将被隐藏,除非您将评论放在某处(“ // DO NOT declare non-POD types here”)。

如果您添加非 POD 类型(或使用非二进制流),生成的错误将是静默数据损坏。

最好为它们中的每一个单独实现;这也不会对使用 POD 施加任何限制,并且实施将遵循最小意外原则。

于 2013-07-24T09:23:51.867 回答
0

根据您的用例,您可能还想查看Boost Serialization Library。虽然这对于简单的用例来说似乎有点过头了,但我发现这个库对于存储不同复杂性的对象非常灵活。

于 2013-07-24T11:11:45.133 回答