Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > C/C++: Общие вопросы > Нужна пара трюков


Автор: freecod 20.09.08, 10:02
Не могу придумать, чем реализовать следущюю задачу:
Нужно создать некотурую структуру формата
int type | dword h1 | dword h2

кол-во элементов нужно динамически увеличивать.
+ от чего возникают проблемы - нужно удалять некоторые элементы, при этом нужно
иметь возможность искать по элементу структуры.
чем бы это реализовать?

Автор: maxim84_ 20.09.08, 10:50
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    typedef struct _Type
    {
      int type
      DWORD h1
      DWORD h2
     
      _Type( int _type, DWORD _h1, DWORD _h2 ): type(_type), h1( _h1 ), h2( _h2 )
      {}
    } StructType;
     
    typedef std::vector<StructType> MyVector;
    typedef MyVector::iterator MyVectorIterator;
     
    MyVector m_stlVector;
     
    /*добавляем элемент*/
    m_stlVector.push_back( StructType( 0,12,12 )  );
    m_stlVector.push_back( StructType( 3,10,11 )  );
     
    /*удаляем элемент*/
    MyVectorIterator i = std::find(m_stlVector.begin(), m_stlVector.end(), StructType( 0,12,12 ));
    if( i != m_stlVector.end() )
      m_stlVector.erase( i );

Автор: freecod 20.09.08, 12:15
Спасибо, а можно таким образом добавлять в определённую позицию определённый элемент?
Например сначала помещаем type и h1
потом по h1 находим элемент и добавляем значение h2?
И удалять не по маске всех элементов сразу, а по какому-то одному, к примеру h2?

Можно ответить просто "можно" и я уйду разбираться с vector =)

Автор: pan2004 20.09.08, 12:59
Цитата freecod @
Спасибо, а можно таким образом добавлять в определённую позицию определённый элемент?

добавлять/удалять элементы из середины вектора можно, но не рекомендуется - при этом будет произведено копирование всего содержимого вектора, и это будет медленно работать на больших массивах данных. Лучше для этого использовать связанные списки типа std::list<>. А вообще ознакомься со всем STL - разнообразными контейнерами, алгоритмами и проч.

Автор: maxim84_ 20.09.08, 13:46
Цитата
добавлять/удалять элементы из середины вектора можно, но не рекомендуется - при этом будет произведено копирование всего содержимого вектора, и это будет медленно работать на больших массивах данных. Лучше для этого использовать связанные списки типа std::list<>. А вообще ознакомься со всем STL - разнообразными контейнерами, алгоритмами и проч.


если парядок не важен, то можно так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    MyVectorIterator i = std::find(m_stlVector.begin(), m_stlVector.end(), StructType( 0,12,12 ));
    if( i != m_stlVector.end() )
    {
      std::swap( i, m_stlVector.end() );
      m_stlVector.erase( m_stlVector.end() );
    }

Автор: qwone 20.09.08, 14:13
freecod
Честно я стандартную библиотеку не знаю . Но для решения этого у меня есть пара заготовок .
инклуде файл с классом . информация ложится в динамическую память . надо расширяю надо сужаю . Но это не шаблон , поэтому подгонка занимает время . Но тупиков в работе поменьше . Надо эту инфру кидаю в файл , надо извлекаю .
так что если полуфабрикат нужен скажи . Если нет то пользуйся тем что предложили.

Автор: freecod 20.09.08, 15:35
Вообще разбираюсь уже с list, но если не жалко - зааттачь, хорошие сорсы лишними не бывают =)

Автор: qwone 20.09.08, 18:23
ну это так для ознакомления структура
см по ссылке только вместо массива твоя структура
http://www.cyberforum.ru/post55082.html

еще вопрос
dword это что char или unsigned short .

Автор: Dem_max 20.09.08, 18:28
dword это 4 байта (double word, word - это слово == 2 байта)
char это 1 байт
unsigned short это 2 байта.

Автор: freecod 20.09.08, 19:42
Цитата Dem_max @
dword это 4 байта (double word, word - это слово == 2 байта)
char это 1 байт
unsigned short это 2 байта.

Может он имел ввиду char * ?

Да, dword это 4 байта, define к unsigned long

Добавлено
Я вот смотрю в STL все контейнеры оерентированны на единичные элементы. То есть даже структура помещается как единичный элемент.
Но у меня такая задача: вот у меня 3 связанных переменных - int и два dword. их - массив. То есть если бы мне было известно необходимое
кол-во элементов я бы задал
struct base{
int type;
DWORD h1;
DWORD h2;
};

base some_base[100];

и использовал бы.
Но у меня есть такой нюанс - по первых мне нужно по любому элементу этой "тройки" (один элемент структуры, "строчка" из [type, h1, h2])
в соотв. "ряду" найти например где h1 == 12345678 и получить позицию этой "тройки". То есть мне это воображается как-то вроде

int pos = find(some_base.h1, 12345678);
DWORD need = some_base[pos].h2;

то есть обращаться к каждому подэлементу и упрявляться с этим.
плюс ещё сколько у меня будет этих "троек" - хз, и они регулярно обновляются - одни удаляю, другие записываю, так что классический struct не подходит...
как можно догадаться - это связаные хендлы, которые группируются в реальном времени.

То есть list в макро-плане удовлетворяет, но как при этом искать по всем h1, а не по тройкам, найти его позицию,
обратится к другим переменным "строки" - не представляю.

Автор: qwone 20.09.08, 20:36
это main.cpp
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
    using namespace std;
    #include "struk.h"
     
     
    int main (){
        truk ST;
        struk A[10];
        for (int i=0;i<10;i++){
                A[i].h1=i;
                A[i].h2=2*i;
                A[i].type=3*i;
                ST.add(A[i]);
                }
        cout << ST;
        cout <<"type=3 N="<<ST.find_type(3)<<endl;
        cout <<"h1=7   N="<<ST.find_h1(7)<<endl;
        cout <<"h2=10  N="<<ST.find_h2(10)<<endl;
        ST.del (5);cout << " del n=5"<<endl;
        cout << ST;
        return 0;
        };


Добавлено
это struk.h
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class struk {
    public:
        int h1;
        int type;
        int h2;
    };
     
    class truk {
    private:
        char Name[20];
        struk * pT; // указатель буфера
        int Len;
    public:
        truk();
        ~truk();
        void clear();       // очиска буфера
        void add(struk & St);   // добавить элемент
        struk get(int i);   // получить элемент
        void del(int i);    // удалить элемент
        int find_type(int i);
        int find_h1  (int i);
        int find_h2  (int i);
        friend ostream& operator<< (ostream& theStream,truk & theString);
     
    };
    truk::truk(){
        pT = new struk[0];
        Len=0;
        }
    truk::~truk(){
        delete []pT;
        Len=0;
        }
    void truk::clear(){
        delete []pT;
        pT = new struk[0];
        Len=0;
        }          
    void truk::add(struk & St){
        struk *pT2= new struk[Len+1];
        int i;
        for(i=0;i<Len;i++)
            pT2[i]=pT[i];
        pT2[i]=St;
        delete []pT;
        pT=pT2;
        Len++;
        }      
    struk truk::get(int i){
        if (i > Len)
            i=Len;
        struk St=pT[i-1];
        return St;
        }      
    void truk::del(int i){
        if ((i<=Len)&&(i!=0)){
            i--;
            struk *pT2= new struk[Len-1];
            int j,k;
            for(j=k=0;k<Len;j++,k++){
                if (i==j)
                    k++;
                pT2[j]=pT[k];
                }
            delete []pT;
            pT=pT2;
            Len--;
            }
        }      
    int truk::find_type(int i){ // k - это найденый номер ; k=0 - такого элемента нет
        int j,k=0;
        for(j=0;j<Len;j++)
            if (pT[j].type==i)
                k=j+1;
        return k;
        }
    int truk::find_h1(int i){
    int j,k=0;
        for(j=0;j<Len;j++)
            if (pT[j].h1==i)
                k=j+1;
        return k;
        }
    int truk::find_h2(int i){
    int j,k=0;
        for(j=0;j<Len;j++)
            if (pT[j].h2==i)
                k=j+1;
        return k;
        }
    ostream & operator << (ostream & theStream,truk & AAA ){
            theStream <<"N"<<"\t"<<"type"<<"\t"<<"h1"<<"\t"<<"h2 "<< endl;
        for (int i=0;i<AAA.Len;i++)
            theStream <<(i+1)<<"\t"<< AAA.pT[i].type <<"\t"<< AAA.pT[i].h1 <<"\t"<< AAA.pT[i].h2 << endl;
        return theStream;
        }


Добавлено
даю тебе словно все int - но если разберешься с кодом
то слепишь все
завтра если тебе надо кину как этот блок записать или считать с винта .

Автор: maxim84_ 20.09.08, 21:24
насчет поиска:
если че не понятно спрашивай.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    typedef struct _BaseStruct
    {
        int type;
        unsigned long h1;
        unsigned long h2;
        
        _BaseStruct(){}
     
        _BaseStruct( int _type, unsigned long _h1, unsigned long _h2)
            : type(_type), h1(_h1), h2(_h2)
        {}
    } BaseStruct;
     
    /*
     
    */
    static bool _f( const BaseStruct& _val, const unsigned long& _f_value )
    {
        return ( _val.h1 == _f_value );
    }
    /*
    */
    template<class TFValue, class container>
    typename container::iterator&
    Find(typename container::iterator& _begin,
              typename container::iterator& _end,
              const TFValue& _FindValue,
              bool (*fun)(const typename container::value_type& _Val, const TFValue& _f_value) )
    {
        typename container::iterator& i = _begin;
        while ( i != _end )
        {
            if( fun( *i, _FindValue ) )
                return i;
            ++i;
        }
     
        return _end;
    }
     
    typedef std::vector<BaseStruct> MyVector;
    typedef MyVector::iterator MyVectorIterator;
    typedef MyVector::const_iterator MyVectorConstIterator;
     
    int _tmain(int argc, _TCHAR* argv[])
    {
        MyVector g_stlVector;
     
        g_stlVector.push_back( BaseStruct(0,1231321,4564654) );
        g_stlVector.push_back( BaseStruct(1,128771,459894) );
        g_stlVector.push_back( BaseStruct(2,1266651,46989894) );
     
        MyVectorIterator i = Find<unsigned long, MyVector>(g_stlVector.begin(),
                                                           g_stlVector.end(),
                                                           1266651,
                                                           &_f );
     
        if( i != g_stlVector.end() )
        {
            printf("type = %d\n"
                   "h1 = %d\n"
                   "h2 = %d\n"
                    ,(*i).type,(*i).h1,(*i).h2);
        }
     
     
        return 0;
    }

Автор: freecod 21.09.08, 07:15
Кстати, вопрос про STL. C подключением чего-либо из STL, например #include <string>, как это влияет на размер и работоспособность на разных win-площадках? как я понимаю класс работы целиком прекомпилируется в бинарник и не требует внешних либ? Как конкретно std::string ведёт себя с большими размерами данных, никаких проблем использовать string как хранилище пары сотен кб данных? И когда я сделаю string = ""; память высвободится?

Автор: qwone 21.09.08, 08:09
это main cpp
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
    #include <fstream>
    using namespace std;
    #include "struk.h"
     
    int main (){
        truk ST;
        struk A[10];
        for (int i=0;i<10;i++){
                A[i].h1=i;
                A[i].h2=2*i;
                A[i].type=3*i;
                ST.add(A[i]);
                }
        cout << ST;
        cout <<"type=3 N="<<ST.find_type(3)<<endl;
        cout <<"h1=7   N="<<ST.find_h1(7)<<endl;
        cout <<"h2=10  N="<<ST.find_h2(10)<<endl;
        ST.del (5);cout << " del n=5"<<endl;
        cout << ST;
        save("file.dn",ST);
        
        truk D;
        load("file.dn",D);
        cout << D;
      
        return 0;
        };


Добавлено
это struk.h

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class struk {
    public:
        int type;
        unsigned long h1;
        unsigned long h2;
    };
     
    class truk {
    private:
        char Name[20];
        struk * pT; // указатель буфера
        int Len;
    public:
        truk();
        ~truk();
        void clear();       // очиска буфера
        void add(struk & St);   // добавить элемент
        struk get(int i);   // получить элемент
        void del(int i);    // удалить элемент
        int find_type(int i);
        int find_h1  (unsigned long i);
        int find_h2  (unsigned long i);
        friend ostream& operator<< (ostream& theStream,truk & theString);
        friend void save(char *NameFile,truk & AA);
        friend void load(char *NameFile,truk & AA);
     
    };
    truk::truk(){
        pT = new struk[0];
        Len=0;
        }
    truk::~truk(){
        delete []pT;
        Len=0;
        }
    void truk::clear(){
        delete []pT;
        pT = new struk[0];
        Len=0;
        }          
    void truk::add(struk & St){
        struk *pT2= new struk[Len+1];
        int i;
        for(i=0;i<Len;i++)
            pT2[i]=pT[i];
        pT2[i]=St;
        delete []pT;
        pT=pT2;
        Len++;
        }      
    struk truk::get(int i){
        if (i > Len)
            i=Len;
        struk St=pT[i-1];
        return St;
        }      
    void truk::del(int i){
        if ((i<=Len)&&(i!=0)){
            i--;
            struk *pT2= new struk[Len-1];
            int j,k;
            for(j=k=0;k<Len;j++,k++){
                if (i==j)
                    k++;
                pT2[j]=pT[k];
                }
            delete []pT;
            pT=pT2;
            Len--;
            }
        }      
    int truk::find_type(int i){ // k - это найденый номер ; k=0 - такого элемента нет
        int j,k=0;
        for(j=0;j<Len;j++)
            if (pT[j].type==i)
                k=j+1;
        return k;
        }
    int truk::find_h1(unsigned long i){
    int j,k=0;
        for(j=0;j<Len;j++)
            if (pT[j].h1==i)
                k=j+1;
        return k;
        }
    int truk::find_h2(unsigned long i){
    int j,k=0;
        for(j=0;j<Len;j++)
            if (pT[j].h2==i)
                k=j+1;
        return k;
        }
    ostream & operator << (ostream & theStream,truk & AAA ){
            theStream <<"N"<<"\t"<<"type"<<"\t"<<"h1"<<"\t"<<"h2 "<< endl;
        for (int i=0;i<AAA.Len;i++)
            theStream <<(i+1)<<"\t"<< AAA.pT[i].type <<"\t"<< AAA.pT[i].h1 <<"\t"<< AAA.pT[i].h2 << endl;
        return theStream;
        }
    void save(char *NameFile,truk & AA){
        ofstream out(NameFile,ios::out |ios::binary);
        if(!out)
            cout <<"files don't open "<<endl;
        else{
            out.write((char*)&AA.Len,sizeof(int));
            out.write((char*)AA.pT,(sizeof(struk)*AA.Len));
            out.close();
            }
    };
     
    void load(char *NameFile,truk & AA){
        ifstream in(NameFile,ios::in |ios::binary);
        if(!in)
            cout <<"files don't open "<<endl;
        else {
            in.read((char*)&AA.Len,sizeof(int));
            AA.pT = new struk[AA.Len];
            in.read((char*)AA.pT,(sizeof(struk)*AA.Len));
            cout<<"READ OK" <<endl;
            in.close();
            }
    };


Добавлено
freecod хоть спасибо скажет ?
ведь в метапрограмировании в шаблонах ему втыкать и не перевтыкать
А тут рабочий код с примером как его запускать

Удачи!!!! :yes:

Добавлено
freecod использовать char если надо обрабатывать побайтно - тупиковый вариант
лучше использовать unsigned short и делить его-побайтно .
тогда можно считать файл целиком и поинтером или масивом к нему добраться

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
    using namespace std;
     
    int main (){
        cout << sizeof(unsigned short)<<" bytes"<< endl;
        unsigned short A=5;
        unsigned short B=A/256;
        unsigned short C=A%256;
        cout <<A<<"\t"<<B <<"\t"<<C<< endl;
        return 0;
    }


ладно я умолкаю и отваливаю подальше . :whistle:

Автор: pan2004 21.09.08, 09:47
Изобретаем велосипеды, господа) Причем еще и одноразового использования...

Цитата freecod @
То есть list в макро-плане удовлетворяет, но как при этом искать по всем h1, а не по тройкам, найти его позицию,
обратится к другим переменным "строки" - не представляю.

Для поиска в контейнерах существуют как минимум 2 стандартных алгоритма: find и find_if. Во втором можно задавать условие для поиска - те искать по одному элементу структуры. К сожалению, при использовании чистого STL это условие должно быть оформлено в виде отдельной функции или класса:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    bool findFunc(const base& elem)
    {
        if (условие) return true;
        return false;
    }
    ...
    iterator elem = std::find_if(mylist.begin(), mylist.end(), &findFunc);

Используя boost, можно уложится и в одну строчку(см boost::bind, boost::lambda)
Например, вызов find_if может выглядеть примерно так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    find_if(mylist.begin(), mylist.end(), bind(&base::getHandle1, _1) == valueISeek);


Цитата qwone @
struk.h

Когда делаешь велосипед, большая вероятность напороться на грабли. Вот и здесь, я бы отметил для начала следующее:
1. Отсутствие конструктора копирования - может привести к ошибкам защиты памяти(типа Segmentation Fault) в некоторых случаях(при копировании объекта, например, при передаче его в качестве аргумента в функцию).
2. Неоптимально реализована функция add(), что будет заметно на более-менее больших объемах данных - каждый раз полностью копируется всё содержимое массива, производится вызовы new[] и delete[]. То же с функцией del().
3. Не шаблон, хотя не так уж и сложно его сделать.
4. Обычно в таких классах перегружается operator[]

Цитата freecod @
Кстати, вопрос про STL. C подключением чего-либо из STL, например #include <string>, как это влияет на размер и работоспособность на разных win-площадках? как я понимаю класс работы целиком прекомпилируется в бинарник и не требует внешних либ?

В STL используются шаблоны, отсюда она полностью header only, те не требует всяких .lib файлов(исключая разве что потоки cin/cout etc), все функции встраиваемые(inline), что положительно влияет на скорость, и отрицательно - на размер. Что касается std::string, то проблем или тормозов при работе с большими файлами не замечал, хотя особенности реализации тут уже зависят от конкретной версии STL.

Автор: maxim84_ 21.09.08, 12:00
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    iterator elem = std::find_if(mylist.begin(), mylist.end(), &findFunc);

pan2004, да, точно...совсем забыл про нее...ну смысл тот же :)

Автор: qwone 21.09.08, 12:41
pan2004 ну а теперь перечисли недостатки шаблонов ?
когда ходишь на ходулях . можно с них быстрее слететь.
шаблоны требуют еще большего знания и опыта.
поэтому не надо спешить лезть на ходули . грабли могут и там тебя достать.

Автор: maxim84_ 21.09.08, 12:44
Цитата
pan2004 ну а теперь перечисли недостатки шаблонов ?
когда ходишь на ходулях . можно с них быстрее слететь.
шаблоны требуют еще большего знания и опыта.
поэтому не надо спешить лезть на ходули . грабли могут и там тебя достать.

углубление в мето-программирование и конструкцию языка еще ни кому не помешали...


в твоих словах я вижу только нежелание...

Автор: pan2004 21.09.08, 13:42
Цитата qwone @
pan2004 ну а теперь перечисли недостатки шаблонов ?

Недостатки? Полно, не спорю. Например, в большинстве компиляторов до сих пор не реализован экспорт шаблонов, так что они - вещи из категории "header only". В смысле кусок шаблона в библиотеку не скомпилируешь, чтобы он там шаблоном и остался.
А если серьезно - нужно бы сравнивать с аналогичными средствами других языков. Таковых я не знаю(очень часто их сравнивают с generics, но это все равно что классы C++ с сишными структурами сравнивать).
Цитата qwone @
когда ходишь на ходулях . можно с них быстрее слететь.
шаблоны требуют еще большего знания и опыта.

Требуют, но начинать то когда-то надо? А то и будете для каждого нового типа данных свой "вектор" изобретать. Кстати, чтобы из этого класса сделать нормальный шаблон, нужно 5 минут(и еще 5 минут потратить на то, чтобы прочитать в учебнике статью - правильно говорят, у страха глаза велики). Для начала уже ничего. Потом присмотритесь к STL, всяких векторов и проч.
Цитата qwone @
поэтому не надо спешить лезть на ходули . грабли могут и там тебя достать.

Дело не в том, что они могут достать, а в том, сколько раз на одни и те же наступишь. Допустим, у тебя в программе пяток подобных классов(как массив к разным типам). Понадобилось добавить конструктор копирования, и придется править каждый, считай 5 раз на грабли наступил(а то и больше, простого копипаста может быть мало). Был бы шаблон - то почуствовал бы всего один удар деревяшкой по лбу). Юзал бы STL - и не пришлось бы вовсе суетится)

Автор: qwone 21.09.08, 17:59
pan2004
почему я не птица - почему не летаю . Если бы юзал STL то и код был другой . Mожет через месяц будет иначе .
И код изменится .Но пока это то что я имею . И то что я собрал . А это неплохая заготовка для идущих следом .

Добавлено
А я пытался сделать шаблон из этого - не получилось . Сможешь сделай . Да и как запустить .с mail тест файлом.

Автор: pan2004 21.09.08, 18:49
Пожалуйста.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <typename T> //Раз
    class truk {
    private:
        T* pT; //Два
        int Len;
    public:
        truk()
        {
            pT = 0;//new T; ?Зачем тут new вообще?
            Len=0;
        }
        truk(truk<T>& const rhs)//Вот этого не было
        {
            if (rhs.pT){ pT = new T[rhs.Len]; for (int i = 0; i < rhs.Len; ++i) pT[i] = rhs.pT[i];}
            else pT = 0;
            Len = rhs.Len;
        }
        ~truk()
        {
            delete []pT;
            Len=0;
        }
        void clear()
        {
            delete []pT;
            pT = 0;//new struk[0]; Тоже - к черту new
            Len=0;
        }        
        void add(T & const St)// Про указатели константности не забываем, когда полезно
       {
           T *pT2= new T[Len+1];
           for(int i=0;i<Len;++i)//Вот это может занимать до 99% времени работы программы. Изменять тут ничего не буду - лучше сразу юзать std::vector<>
              pT2[i]=pT[i];
           pT2[Len++]=St;
           delete []pT;
           pT=pT2;
        }
        T get(int i)const//Ха, тут даже не получится элемент контейнера извне изменить!
        {
           if (i > Len)
               i=Len;
           if (i <= 0) i = 1;
           return pT[i-1];
        }      
        void del(int i)
        {
            // А если мало элементов?
            if (Len == 0 || (Len == 1 && i == 1))
            {
               Len = 0; delete []pT; pT = 0; return;
            }
            if ((i<=Len)&&(i>0))
            {
               i--;
               T *pT2= new T[Len-1];
               int j,k;
               for(j=k=0;k<Len;j++,k++){
                   if (i==j)
                       k++;
                   pT2[j]=pT[k];
                   }
               delete []pT;
               pT=pT2;
               Len--;
            }
        }
    };

сложно?

Автор: qwone 21.09.08, 19:09
спасибо.
где то подобное я переставлял себе . может бы пару моментов бы упустил .Или не пару.
только не думаю что vector быстрее будет . хотя С++ не ассемблер и компилятор не идеальный код сделает .
только вот не пойму как vector это обойдет .

Автор: maxim84_ 21.09.08, 19:19
Цитата
только вот не пойму как vector это обойдет .

дело в том что вестор выделяет память на много элементов вперед. т.е. релокация памяти происходит не каждое добавление, а только тогда, когда место поджмает. и когда удаляются элементы, память не особождается. т.е. если был вектор на 10 элементов, а добавили 100, то после удаления размер заризервированной памяти так и остантся для 100 элементов.

Автор: freecod 21.09.08, 19:37
qwone: не заметил, отписал последний вопрос и завалился спать. Так что торжественное спасибо, it's work =)

Добавлено
Но все таки, если мне нужно быстрое решение по добавлению и удалению элементов - лучше использовать list? Плюс - как искать по конкретному "столбцу" части элемента понятно, очень прошу объяснить как к конкретному элеенту обратиться. Я сейчас мечусь между готовым классом от qwone и потенциально быстрым list... И <base_class><list_class>::<..._...> ... и ещё много такого в объявлении list честно говоря пугают =)

Автор: freecod 22.09.08, 06:47
вожусь с list. по примеру из книжки не хочет работать

struct base {
int type;
HANDLE h1;
HANDLE h2;
std::string mem_page;
DWORD page_size;
};

std::list <base> hold;

main{
// не пашет добавление =(
hold.push_back(base(i, 0,0,"",0)); // мне при создании элемента нужно записать type и h1, остальные элементы не определенны

...

find // теперь найти по h1?
// и сразу записать в этот элемент значение h2 и mem_page

// а теперь по h2 найти элемент и удалить его

Автор: trainer 22.09.08, 10:17
конструктор определи для структуры.
А еще лучше - почитай что-нибудь умное по C++

Автор: D_KEY 22.09.08, 11:14
Цитата freecod @
вожусь с list. по примеру из книжки не хочет работать

struct base {
int type;
HANDLE h1;
HANDLE h2;
std::string mem_page;
DWORD page_size;
};

std::list <base> hold;

main{
// не пашет добавление =(
hold.push_back(base(i, 0,0,"",0)); // мне при создании элемента нужно записать type и h1, остальные элементы не определенны

...

find // теперь найти по h1?
// и сразу записать в этот элемент значение h2 и mem_page

// а теперь по h2 найти элемент и удалить его

Что за книжка такая, в которой такую чушь пишут ;) ? Как уже сказал trainer, определи конструктор, который вызываешь при помещении элемента в список.
Вот тут, ты вызываешь конструктор base( i, 0, 0, "", 0 ):
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    hold.push_back(base(i, 0,0,"",0));

Но определние этого конструктора в описании класса отсутствует.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct base {
        int type;
        HANDLE h1;
        HANDLE h2;
        std::string mem_page;
        DWORD page_size;
        // добавляем конструктор:
        base( int, HANDLE, HANDLE, const std::string &, DWORD );
     
    };

Ну и естественно, нужно реализовать этот конструктор ;)
Может быть еще дефолтовый конструктор тоже понадобится.

Автор: maxim84_ 22.09.08, 11:19
Цитата
Может быть еще дефолтовый конструктор тоже понадобится.

понадобится...

Автор: D_KEY 22.09.08, 11:29
Цитата maxim84_ @
Цитата
Может быть еще дефолтовый конструктор тоже понадобится.

понадобится...

Теоретически - необязательно.

Автор: qwone 22.09.08, 18:31
freecod можно бы и и сделать вектороподобным - алгоритм <vector> я понял как он работает . там надо просто с запасом брать память и просто двигать , а не создавать заново.
или даже <deque> . <list> тоже можно эмулировать .Hо действительно , как сказал pan2004 надо расти дальше .
Вот и буду расти.

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)