Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Работа с массивом объектов

50K
12 июля 2012 года
Roman_pilot
16 / / 10.02.2010
Здравствуйте. При работе с массивом объектов столкнулся со следующей проблемой: у меня есть массив объектов, я обращаюсь в цикле к объектам класса, которые являются элементами массива объектов, обращение подразумевает вызов функций членов класса для каждого объекта. Проблема в следующем: при выполнении функций членов класса переписываются данные переменных членов класса во всех элементах массива объектов, а не только в том для которого данная была вызвана.

Код:
//описание класса
class Parse
{
public:
    obj *object; //указатель на массив объектов, упомянутый в вопросе
    int num_of_obj;
    void add_obj();//-
    ...
    void process();
    ...
    ~Parse();
    Parse(char *indata, int length);
        ...
    static char * tmp; //указатель на временный массив, используемый для нарезания пакета на объекты, объектов на структуры
    static int tmp_size;
    ...
} ;

class obj{

public:
...
...
        int proc_obj(char *indata,  int length); //парсинг объекта
...
        obj(){};
        ~obj();
};

//---------------------

void Parse::process(){
    int cur_pos=0;
    int count=0;
    if(check_size()!=-1){
        do {
            ...
            add_obj();//функция добавления элемента в массив объектов
            ...
//вызов функции обработки для объекта
            if(!object[count].proc_obj(temp, temp_size)){} //на входе статические переменные.
//данная функция записывает одинаковые данные во все элементы массива
            ...
            ...
            ...
            cur_pos=cur_pos+cut_bytes+1;
            count++;
        }
        ...
}
//-------функция добавления объекта в массив, дебагил, отрабатывает правильно
void Parse::add_obj(){
    int num_of_fuildes;
    if (num_of_obj==-1) {
        object=new obj[num_of_obj+2];
        num_of_obj++;
    }
    else{
        obj *temp;
        temp=new obj[num_of_obj+2];
        for (int i = 0; i <= num_of_obj; i++) {
            temp[num_of_obj]=object[num_of_obj];
            num_of_fuildes=temp[0].type->num_of_fuild;
        }
        delete [] object;
        object=new obj[num_of_obj+2];
        for (int i = 0; i <= num_of_obj; i++) {
            object[num_of_obj]=temp[num_of_obj];
            num_of_fuildes=object[i].type->num_of_fuild;
        }
        delete [] temp;
        num_of_fuildes=object[0].type->num_of_fuild;
        num_of_obj++;
    }
 }
В функции добавления объекта свойства предыдущего объекта массива сохраняются корректные, перезапись всех свойств происходит именно после вызова функции proc_obj().
Подозреваю, что массив объектов воспринимается как один объект и поэтому переписываются переменные-члены всех его элементов.
Вопрос:
- как сделать так чтобы функция-член работала только с одним элементом?
- если сделать временный объект, а потом скопировать его в массив объектов, то как прописывать копирующий конструктор: просто тупо при помощи memcpy, зная размер каждого элемента подставлять увеличенные значения индексов, или есть решения по-красивей?
- в общем, хотелось бы узнать как это все по науке делается, а не при помощи рукопашного копирования памяти memcy.
  • Что в proc_obj? от CassandraDied, 12 июля 2012 года
50K
13 июля 2012 года
Roman_pilot
16 / / 10.02.2010
Уточнение.
функция proc_obj

Код:
int obj::proc_obj(char *indata,  int length){
    //---------------
    obj_size=length;
    obj_data=new char[obj_size];
    memcpy((void*)&obj_data[0], (void*)&indata[0], obj_size);
    delete []indata;
    //---------------

    ...
        type=new sub_obj(); //type объект класса, объявлен в классе obj
        if(type->proc_sub()==-1){// функция отрабатывает как надо, для одного объекта однако она переписывает все элементы одними и теми же значениями,
    ...
    ...
    return -1;

}

int sub_obj::proc_sub(){
    ...
    ...
    proc_field()
    return 0;
}
int sub_obj::proc_field(){
    int fuild_size=Parse::tmp_size;
    char *fuild_data;
    fuild_data=new char[fuild_size];
    memcpy((void*)&fuild_data[0], (void*)&Parse::tmp[0], fuild_size);
    delete []Parse::tmp;
    AnsiString str=AnsiString(&fuild_data[0], fuild_size);
    ...
    ins_field(str);

    delete[] fuild_data;
    return 0;
}
void sub_obj::ins_field(AnsiString temp){
    if (num_of_field==-1) {
        field=new TStringList;
        num_of_field++;//инициализируется конструктором, -1
        field->Add(temp);
        AnsiString temp=field->Strings[0];
    }
    else {
        num_of_fuild++;
        field->Add(temp);
        AnsiString temp=field->Strings[num_of_field];
    }
}
//когда я после proc_obj в функции process() на втором шаге вызываю для дебагинга:
    num_of_fuildes=object[0].type->num_of_fuild;
//для проверки данных в первого объекте массива он мне выдает значения второго элемента
При выводе в файл всех значений массива, вижу что оба объекта в массиве заполнены одинаковыми значениями.
Если в массиве один элемент то все отрабатывает как надо.
414
13 июля 2012 года
CassandraDied
763 / / 24.05.2012
Бегло просмотрев код, могу посоветовать вместо копирования всего объсекта
 
Код:
memcpy((void*)&obj_data[0], (void*)&indata[0], obj_size);
Копировать каждое его поле отдельно. Этим и занимается конструктор копирования. Нагуглить, думаю, сам сможешь, как его писать - там ничего сложного.
Что мешает передавать указатель на объект вместо указателя на char? Так хотя бы понятнее было, что происходит вообще. Если мой совет не поможет, то залей сюда полные исходники, без многоточий. Только не вставляй его через тег форматирования кода, есть такая фича, как прикрепление файла.
50K
14 июля 2012 года
Roman_pilot
16 / / 10.02.2010
Спасибо, буду пробовать.
Что касается аргументов функции proc_obj(), так там передается текстовая строка, которую надо распарсить, создать объект и заполнить его поля тем, что распарсили, так как proc_obj() как раз и занимается парсингом своей части исходной строки, ей передается эта строка. П.С. конечная задача разбор пакета JSON.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог