Использование низкоуровневых вещей, таких как массивы, мало чем поможет, это уже слишком сложно.Кроме того, это может привести к адским проблемам с совместимостью (например, думать о порядке следования байтов).
Если у вас нет очень строгих ограничений производительности, используйте вместо этого решение, разработанное специально для работы в сети: буферы протокола .Это немного излишне для вашего случая, но хорошо масштабируется, если вам нужно что-то добавить.
Чтобы использовать буферы протокола, вы сначала определяете «сообщения» (структуры) в файле .proto
, затемскомпилируйте их в C ++ с помощью Proto Compiler.
Вы определяете свое сообщение следующим образом (это полный файл .proto
):
syntax = "proto2";
package test;
message Storage {
message Row {
repeated string foo = 1;
}
repeated Row row = 1;
}
Прямая поддержка 2D-массивов отсутствует, нос массивом массивов все будет в порядке (repeated
означает, что в данном поле может быть несколько значений, в основном это вектор).Вы можете добавить поля для размера массива, если вам нужен быстрый доступ к ним, но проверки размера повторяющихся полей должно быть достаточно в большинстве практических случаев.
То, что вы получаете, это класс, который имеет все необходимые поля,заботится об управлении памятью и имеет кучу методов для сериализации и десериализации .
Код на C ++ становится немного длиннее в некоторых местах, так как вам нужно использовать методы получения и установки, но этодолжно быть хорошо компенсировано тем, что вам никогда не нужно думать о сериализации - это происходит само по себе.
Пример использования этой вещи в C ++ может выглядеть так:
#include "test.pb.h" // Generated from test.proto
using ::test::Storage;
int main() {
Storage s;
Storage::Row* row1 = s.add_row();
row1->add_foo("foo 0,0");
row1->add_foo("foo 0,1");
Storage::Row* row2 = s.add_row();
row2->add_foo("foo 1,0");
row2->add_foo("foo 1,1");
assert(s.row_size() == 2);
assert(s.row(0).foo_size() == 2);
s.PrintDebugString(); // prints to stdout
}
InВ результате вы получите этот вывод (обратите внимание, что это отладочный вывод, а не реальная сериализация):
row {
foo: "foo 0,0"
foo: "foo 0,1"
}
row {
foo: "foo 1,0"
foo: "foo 1,1"
}
Для полноты: в приведенном выше примере исходные файлы были test.proto
и test.cpp
, скомпилированные с использованием:
protoc --cpp_out=. test.proto
g++ test.cpp test.pb.cc -o test -lprotobuf