-1

STL を使用せずに C++ で永続化を使用する方法について質問があります。計算の履歴をメモリに保存し、プログラムが呼び出されるたびに新しい計算で更新したいと考えています。実行後、メモリが失われるため、静的ストレージクラスを使用できません。

どんなポインタでも役立ちます。ストリーミングは正しいアプローチですか?

4

1 に答える 1

1

最も簡単なのは、ディスク上で構造体を読み書きすることです。まず、保存するものを定義します。

struct SavedState {
    int32_t a;
    float b;
    char c[100]; // n.b. you cannot use std::string here!
} __attribute__((__packed__));

static_assert(std::is_trivially_copyable<SavedState>::value,
              "SavedState must be trivially copyable");

次に、状態を作成して保存します。

SavedState s = { 1, 2.3 };
snprintf(s.c, sizeof(s.c), "hello world!");
std::ofstream outfile("saved.state", std::ios::binary);
outfile.write(reinterpret_cast<char*>(&s), sizeof(s));
if (!outfile)
    std::runtime_error("failed to write");

次に、復元します。

SavedState t;
std::ifstream infile("saved.state", std::ios::binary);
infile.read(reinterpret_cast<char*>(&t), sizeof(t));
if (!infile)
    throw std::runtime_error("failed to read");

いくつかの重要な注意事項:

  1. std::ios::binaryストリームが改行を「正規化」するのを防ぐために必要です(テキストではなくバイナリデータを保存しています)。
  2. __packed__構造体がすべてのシステムで同じサイズであることを確認するために必要です。int32_tただの代わりに同上int
  3. このコードは「エンディアン」の問題を処理しません。つまり、マシンの同じ「エンディアン」で状態を保存および復元する必要があるため、たとえば x86 で保存して SPARC でロードすることはできません。
  4. つまり、ほとんどの STL コンテナー、文字列、またはその他の動的にサイズ変更される要素を含めることはできません。C++11 では、コンパイル時にstatic_assert;を使用してこれを保証できます。以前のバージョンの C++ では、必要に応じて使用できBOOST_STATIC_ASSERTます。
于 2015-12-15T05:49:53.273 に答える