Подскажите с STL, что лучше использовать
От: SilverAurum  
Дата: 25.09.04 12:41
Оценка:
Я никогда не имел дела c STL, а вот сейчас кажется назрела необходимость...

Мне в программе необходимо где-то хранить различные структуры данных, считанных из некоего устройства.
Каждая структура имеет свой уникальный идентификатор.
Какой из контейнеров лучше применить для этого, и как лучше реализовать?

Я мыслю сдеалать класс типа:


class TDataArea    
{
    int    area_id,
            area_len;
    char    *data;

    TDataArea( void );
    TDataArea( int id, int len, char *buf );
    ~TDataArea( void );
};


и хранить экземпляры этого класса в <vector>, допустим
А при необходимости получить хранимые данные явно приводить TDataArea->data к необходимой структуре, ориентируясь по TDataArea->area_id
Использование примерно следующим образом (в сильно упрощенном виде):

vector <TDataArea> DataStorage;

...
// получение данных размером 10 байт в масиив buf.
...

// сохранение полученых данных:
TDataArea    a( 1, 10, buf );
DataStorage.push_back( a );

...
// извлечение данных:
TDataArea    b;
b    =    DataStorage[0];

TSomeStruct *s    =    (TSomeStruct*)b.data;
...


Корректно ли делать нечто подобное, или можно найти другое решение, более правильное и красивое?
Re: Подскажите с STL,что лучше использовать
От: Nazik Россия  
Дата: 25.09.04 15:00
Оценка:
Все зависит от того, какие возможности требуются от контейнера — ключ (map), вохиожность удалять и вставлять где-попало (list) или скорость (deque). А если нужен "динамический массив" — сделано нормально!

"SilverAurum" <30413@news.rsdn.ru> сообщил/сообщила в новостях следующее: news:824527@news.rsdn.ru...
> Я никогда не имел дела c STL, а вот сейчас кажется назрела необходимость...
>
> Мне в программе необходимо где-то хранить различные структуры данных, считанных из некоего устройства.
> Каждая структура имеет свой уникальный идентификатор.
> Какой из контейнеров лучше применить для этого, и как лучше реализовать?
>
> Я мыслю сдеалать класс типа:
>
>
>
> class TDataArea 
> {
> int area_id,
> area_len;
> char *data;
> 
> TDataArea( void );
> TDataArea( int id, int len, char *buf );
> ~TDataArea( void );
> };
>

>
> и хранить экземпляры этого класса в <vector>, допустим
> А при необходимости получить хранимые данные явно приводить TDataArea->data к необходимой структуре, ориентируясь по TDataArea->area_id
> Использование примерно следующим образом (в сильно упрощенном виде):
>
>
> vector <TDataArea> DataStorage;
> 
> ...
> // получение данных размером 10 байт в масиив buf.
> ...
> 
> // сохранение полученых данных:
> TDataArea a( 1, 10, buf );
> DataStorage.push_back( a );
> 
> ...
> // извлечение данных:
> TDataArea b;
> b = DataStorage[0];
> 
> TSomeStruct *s = (TSomeStruct*)b.data;
> ...
> 
>

>
> Корректно ли делать нечто подобное, или можно найти другое решение, более правильное и красивое?
Posted via RSDN NNTP Server 1.9 gamma
Re[2]: Подскажите с STL,что лучше использовать
От: SilverAurum  
Дата: 26.09.04 11:50
Оценка:
Здравствуйте, Nazik, Вы писали:

N>Все зависит от того, какие возможности требуются от контейнера — ключ (map), вохиожность удалять и вставлять где-попало (list) или скорость (deque). А если нужен "динамический массив" — сделано нормально!


Нужен именно динамический массив, без возможности удаления-вставки где попало... Скорость работы — да, нужна. Быстрее ли будет при использовании доступа по ключу (map), чем при простом переборе всех записей в vector? Кол-во записей в массиве — в среднем около 50. Немного, но таких массивов будет множество, возможно потребуется перебор всех массивов в БД...

И еще вопрос: есть ли какие-то стандартные методы получения всех записей из массива (реализованного в vector или list,map и т.д.) с целью последующего сохранения где-либо, в файле или БД (в виде одной BLOB записи)? И есть ли возможность потом проинициализировать этой записью тот же vector или map? Или надо писать свой метод, который пройдется по всему массиву и накидает все записи в буфер? (и другой метод, который потом будет разбирать эту запись на отдельные записи и вставлять по одной...)

Спасибо за ответ!
Re[3]: Подскажите с STL,что лучше использовать
От: Nuald Россия http://nuald.blogspot.com
Дата: 27.09.04 00:37
Оценка:
Здравствуйте, SilverAurum, Вы писали:

SA>Нужен именно динамический массив, без возможности удаления-вставки где попало... Скорость работы — да, нужна. Быстрее ли будет при использовании доступа по ключу (map), чем при простом переборе всех записей в vector? Кол-во записей в массиве — в среднем около 50. Немного, но таких массивов будет множество, возможно потребуется перебор всех массивов в БД...


Если вставлять только в конец, то лучше подойдет очередь (скорость доступа — const).
Если всегда осуществляется последовательный доступ через итераторы, то опять-таки вектора и очереди выигрывают (скорость доступа — const, у ассоциативного массива — O(log n)).

SA>И еще вопрос: есть ли какие-то стандартные методы получения всех записей из массива (реализованного в vector или list,map и т.д.) с целью последующего сохранения где-либо, в файле или БД (в виде одной BLOB записи)? И есть ли возможность потом проинициализировать этой записью тот же vector или map? Или надо писать свой метод, который пройдется по всему массиву и накидает все записи в буфер? (и другой метод, который потом будет разбирать эту запись на отдельные записи и вставлять по одной...)


В сущности это можно организовать, но такое решение будет зависимым от платформы. Можно использовать потоки — std::stringstream, а потом сохранять куда нужно.
Приведу пример:
class TDataArea {
    int area_id; // area_len больше не нужен, т.к. используем string
    std::string data; // заменяем на string, использование char* чревато

public:
    TDataArea();
    TDataArea(int id, const string& buf);
    ~TDataArea();
    const char* getData() { return data.c_str(); }
    friend ostream& operator << (ostream&, const TDataArea&);
    friend istream& operator >> (istream&, const TDataArea&);
};

int main() {
  vector <TDataArea> dataStorage;
  DataTableGateway gate; //какой-то объект доступа к БД
  gate.initialize();
  for (int i = 0; i < gate.size(); ++i) {
    // получение данных размером 10 байт в масиив buf.
    std::string data = gate[i];
    // сохранение полученых данных:
    TDataArea a(i, data);
    dataStorage.push_back(a);
  }

  // извлечение данных:
  TDataArea b;
  b = dataStorage[0];
  TSomeStruct s(b.getData()); //если использовать в данном контексте, то лучше вообще подумать о шаблонах

  // сохраняем в поток
  std::stringstream s;
  s << b;

  // извлекаем из потока
  TDataArea a;
  s >> a;

  // сохраняем в объект доступа к БД
  gate.append(s.str().c_str());
};

ИМХО, если вы работаете с однотипными структурами, то вам лучше сделать TDataArea шаблоном.
Re[4]: Подскажите с STL,что лучше использовать
От: SilverAurum  
Дата: 27.09.04 07:25
Оценка:
Здравствуйте, Nuald, Вы писали:


SA>>И еще вопрос: есть ли какие-то стандартные методы получения всех записей из массива (реализованного в vector или list,map и т.д.) с целью последующего сохранения где-либо, в файле или БД (в виде одной BLOB записи)? И есть ли возможность потом проинициализировать этой записью тот же vector или map? Или надо писать свой метод, который пройдется по всему массиву и накидает все записи в буфер? (и другой метод, который потом будет разбирать эту запись на отдельные записи и вставлять по одной...)


N>В сущности это можно организовать, но такое решение будет зависимым от платформы. Можно использовать потоки — std::stringstream, а потом сохранять куда нужно.

N>Приведу пример:

Это не совсем то, что я имел ввиду... Мне нужно сохранять все содержимое вектора в одной записи (или строке, в том же char*), что-то типа:

vector <TSomeData> d;
TBlobField f;

d.SaveToBase( f );

...

// и затем загружаем из базы весь вектор за один проход:
d.LoadFromBase( f );


Понятно, что можно реализовать SaveToBase и LoadFromBase самому, на основе перебора всех записей в векторе, но может быть есть уже какие-то реализованные методы, позволяющие сохранить и прочитать соджержимое всего вектора?


N>ИМХО, если вы работаете с однотипными структурами, то вам лучше сделать TDataArea шаблоном.


Нет, структуры разнородные
Re[3]: Подскажите с STL,что лучше использовать
От: ssm Россия  
Дата: 27.09.04 07:31
Оценка:
Здравствуйте, SilverAurum, Вы писали:


SA>Нужен именно динамический массив, без возможности удаления-вставки где попало... Скорость работы — да, нужна. Быстрее ли будет при использовании доступа по ключу (map), чем при простом переборе всех записей в vector?


ну map конечно быстрее , но вставлять в него намного медленней
как альтернативу map — попробуй сортированный вектор
Re[5]: Подскажите с STL,что лучше использовать
От: Nuald Россия http://nuald.blogspot.com
Дата: 27.09.04 23:46
Оценка:
Здравствуйте, SilverAurum, Вы писали:

SA>Это не совсем то, что я имел ввиду... Мне нужно сохранять все содержимое вектора в одной записи (или строке, в том же char*), что-то типа:

SA>
SA>vector <TSomeData> d;
SA>TBlobField f;
SA>d.SaveToBase( f );
SA>...
SA>// и затем загружаем из базы весь вектор за один проход:
SA>d.LoadFromBase( f ); 
SA>


SA>Понятно, что можно реализовать SaveToBase и LoadFromBase самому, на основе перебора всех записей в векторе, но может быть есть уже какие-то реализованные методы, позволяющие сохранить и прочитать соджержимое всего вектора?


Для этого используется обобщенное программирование:
std::stringstream stream; //наш поток

std::istream_iterator<TSomeData> beginStream(stream); // начало потока
std::istream_iterator<TSomeData> endStream; // конец потока
std::vector<TSomeData> d(beginStream, endStream); // прочитали из потока

std::ostream_iterator<TSomeData> streamWriter(stream); // итератор записи в поток
std::copy(d.begin(), d.end(), streamWriter); // записали в поток

Данную запись можно упростить, используя шаблоны...
Re: Подскажите с STL, что лучше использовать
От: SWW Россия  
Дата: 28.09.04 05:41
Оценка:
SA>
SA>class TDataArea    
SA>{
SA>    int    area_id,
SA>            area_len;
SA>    char    *data;

SA>    TDataArea( void );
SA>    TDataArea( int id, int len, char *buf );
SA>    ~TDataArea( void );
SA>};
SA>


SA>и хранить экземпляры этого класса в <vector>, допустим

SA>А при необходимости получить хранимые данные явно приводить TDataArea->data к необходимой структуре, ориентируясь по TDataArea->area_id

Может лучше так:
class TDataArea    
{
    int    area_id,
        area_len;
    union {
        struct_for_id1    id1;
        struct_for_id2    id2;
        struct_for_id3    id3;
        // ...
        char    data[512];
    };

    TDataArea( void );
    TDataArea( int id, int len, char *buf );
    ~TDataArea( void );
};


Чтобы не приводить data к необходимой структуре.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.