Строки в стиле C всегда можно преобразовать в std::string по мере необходимости. На самом деле, есть хороший шанс, что ваши наблюдения из профилирования связаны с фрагментацией ваших данных, а не просто с количеством распределений, и создание std::string по требованию будет эффективным. Конечно, не зная вашего фактического приложения, это всего лишь предположение, и на самом деле никто не может этого знать, пока оно не будет проверено. Я представляю себе класс
class my_class {
std::string data() const { return self._data; }
const char* data_as_c_str() const // In case you really need it!
{ return self._data; }
private:
int _type;
char _data[1];
};
Примечание. Я использовал стандартный хитрый прием C для размещения данных: _data имеет длину, которую вы хотите, если ваша фабричная функция выделяет для него дополнительное пространство. IIRC, C99 даже предоставил для него специальный синтаксис:
struct my_struct {
int type;
char data[];
};
который имеет хорошие шансы работать с вашим компилятором C++. (Это в стандарте С++ 11?)
Конечно, если вы сделаете это, вам действительно нужно сделать все конструкторы частными и дружественными к вашей фабричной функции, чтобы убедиться, что фабричная функция является единственным способом фактического создания экземпляра my_class — он будет сломан без дополнительной памяти для массив. Вам обязательно нужно сделать operator= закрытым или иным образом тщательно реализовать его.
Переосмысление ваших типов данных, вероятно, является хорошей идеей.
Например, вы можете вместо того, чтобы пытаться поместить свои массивы char в структурированный тип данных, использовать интеллектуальную ссылку. Класс, похожий на
class structured_data_reference {
public:
structured_data_reference(const char *data):_data(data) {}
std::string get_first_field() const {
// Do something interesting with _data to get the first field
}
private:
const char *_data;
};
Вы также захотите поступить правильно с другими конструкторами и оператором присваивания (возможно, отключите присваивание и реализуйте что-то разумное для перемещения и копирования). И вам могут понадобиться указатели с подсчетом ссылок (например, std::shared_ptr) в вашем коде, а не голые указатели.
Другой возможный хак — просто использовать std::string, но хранить информацию о типе в первой записи (или в первых нескольких). Конечно, это требует учета этого всякий раз, когда вы получаете доступ к данным.
person
Community
schedule
08.06.2012
char*? Худшие части строк C — это необходимость управлять памятью, но кажется, что в вашем случае это не проблема, не так ли? - person David Rodríguez - dribeas   schedule 08.06.2012std::string, а не c-строку, вы можете рассмотреть возможность использования пользовательского распределителя для достижения того, что вы хотите сделать. Это может позволить вам объединить ваши строки в одном выделении, но все равно не будет выделено все (то есть ваша структура) за один раз, и это, вероятно, станет кошмаром обслуживания. Вероятно, лучше всего придерживаться c-strings. - person Component 10   schedule 08.06.2012