我不明白的std :: vector元素错误

时间:2018-09-01 20:07:24

标签: c++ templates vector

im试图以我自己的方式创建一个函数来序列化一个类。我正在使用一个模板来保存每种形式的原始变量。即时通讯在我的序列化功能中出现错误。我不想我的元素在我的结构b / c中是静态的,我想保存许多不同的随机元素,请帮忙!

struct _PVS
{
public:
    template<typename _PV> _PVS(_PV &PV)
        : ele(PV)
    {}
    template<typename _PV> _PV ele;
};
class player_one {

    std::vector<_PVS*> serializing;

    const string PL_name = "JOHN!";
    unsigned short int hp = 100;
    unsigned short int shield = 55;
    string fav_food = "soup.";

public:

    player_one() {

        serializing.push_back(new _PVS(PL_name));
        serializing.push_back(new _PVS(hp));
        serializing.push_back(new _PVS(shield));
        serializing.push_back(new _PVS(fav_food));

    }

    void serialclass() {
        ofstream _F;
        string temp;
        _F.open("player_one.log");

        for (int i = 0; i < serializing.size(); i++) {
        temp = (std::string)serializing[i].ele;
            //getline to pass in whole lines for data for serializing
        }



    };

};

1 个答案:

答案 0 :(得分:0)

二进制序列化

下面是一个示例,说明了如何对低级文件格式进行序列化。请注意,我们只知道如何序列化两个字段类型(let x = 4;; (* Declare x *) let f y = x + y;; (* Use x *) let x = 5;; (* Declare a new variable with the same name as x *) assert (f 10 = 14);; (* The x = 4 definition is used, as x is immutable *) uint16_t)。您可以根据需要专门化其他类型。

数据格式

我们要做的第一件事是选择一种数据格式。我在下面使用了一种基于块的简单方法,其中为每个字段的类型和长度保留了两个字节。每当您要序列化字段时,首先要写一个代表该类型的数字,然后写一个指示标头后面有多少字节的数字。

这被称为可变长度编码。

示例代码

std::string

样本输出

注意:下面的字符串以十六进制格式编码。字符串不以null结尾,以节省二进制格式的空间。反序列化时,您必须重新应用空字节终止符。

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <cstdint>
#include <iomanip>

using namespace std;

enum class SerializedType {
    Unknown,
    UnsignedShortInteger,
    String
};
struct mapInt {
public:
    const uint8_t first;
    const uint8_t second;
    mapInt(uint16_t value)
    : first((value & 0xff00)>>8),
      second(value & 0xff) {
    }
};

std::vector<uint8_t> toWireFormat(const uint16_t& value) {
    const auto mapped = mapInt(value);
    const std::vector<uint8_t> data = {
        static_cast<uint8_t>(SerializedType::UnsignedShortInteger),
        2,
        mapped.first,
        mapped.second
    };
    return data;
}

std::vector<uint8_t> toWireFormat(const std::string& value) {
    std::vector<uint8_t> data;
    data.resize(value.size() + 2);
    data[0] = static_cast<uint8_t>(SerializedType::String);
    data[1] = static_cast<uint8_t>(value.size());
    for (auto i = 0; i < value.size(); ++i) {
        data[i+2] = value.at(i);
    }
    return data;
}

std::string serializedTypeAsString(SerializedType type) {
    switch (type) {
        case SerializedType::Unknown:
            return " Unknown";
        case SerializedType::UnsignedShortInteger:
            return "uint16_t";
        case SerializedType::String:
            return "  string";
    }
}

template<class T>
void appendData(std::vector<uint8_t>& data, const T& value) {
    const auto buffer = toWireFormat(value);
    data.insert(data.end(), buffer.begin(), buffer.end());
}

class PlayerOne {
public:
    const string name;
    uint16_t hp;
    uint16_t shield;
    string favFood = "soup";

    PlayerOne() = default;
    ~PlayerOne() = default;

    void serialize(std::vector<uint8_t>& data) const {
        appendData(data, name);
        appendData(data, hp);
        appendData(data, shield);
        appendData(data, favFood);
    };
};

int main()
{
   PlayerOne ready = { "JOHN!", 100, 55, "Soup" };
   PlayerOne two = { "Sarah", 250, 0, "Cake" };

    vector<uint8_t> output;
    ready.serialize(output);
    two.serialize(output);

    cout << "Serialized two objects into " << output.size() << " bytes." << endl;
    size_t i = 0;
    while (i < output.size()) {
        const auto typeString = serializedTypeAsString(
            static_cast<SerializedType>(output.at(i)));
        const int length = output.at(i+1);
        cout << "\nType: " << typeString << ", Length: " << length << ", Data: ";
        i += 2;
        if ((i+length) > output.size()) {
            break;
        }
        for (size_t j = i; j < (i+length); ++j) {
            cout << hex << setfill('0') << setw(2) << static_cast<int>(output.at(j));
        }
        i += length;
    }
    cout << endl;
    return 0;
}