Russian Qt Forum
Ноябрь 25, 2024, 01:27 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QList  (Прочитано 3722 раз)
Primordial
Гость
« : Июль 09, 2012, 22:52 »

Возник небольшой вопросец по использованию списков. Пусть есть какой-нибудь класс, например:
Код:
class MyClass
{
private:
    float x, y, z;

public:
    MyClass();
    MyClass(float _x, float _y, float _z);

    float GetX();
    void SetX(float _x);

    //  ...
    //  ...
    //  ...

};

Пример использования с QList:
Код:
QList<MyClass> listMyClass;
QList<MyClass*> listMyClassP;


void AddToListA(float x, float y, float z)
{
    MyClass myClassInstance(x, y, z);
    listMyClass.push_back(myClassInstance);
}


void AddToListB(float x, float y, float z)
{
    MyClass myClassInstance(x, y, z);
    listMyClassP.push_back(&myClassInstance);
}


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
   
    for (int i = 0; i < 10; i++)
    {
        AddToListA(i, i, i);
        AddToListB(i, i, i);
    }

    return a.exec();
}
Меня интересует необходимость освобождение ресурсов в случаях с "QList<MyClass> listMyClass" и "QList<MyClass*> listMyClassP". Будет ли память подчищена автоматически? Я склоняюсь к тому, что в случае "QList<MyClass> listMyClass" - да.
Записан
alexis031182
Гость
« Ответ #1 : Июль 09, 2012, 23:28 »

В обоих случаях.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #2 : Июль 10, 2012, 07:33 »

Нет, полный бред(

Особенно вот этот фрагмент, меня веселит:
Код
C++ (Qt)
void AddToListB(float x, float y, float z)
{
   MyClass myClassInstance(x, y, z);
   listMyClassP.push_back(&myClassInstance);
}
 

Можно, например, сделать так:
Код
C++ (Qt)
int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
 
   for (int i = 0; i < 10; i++)
   {
       listMyClass.append(MyClass(i, i, i));
       listMyClassP.append(new MyClass(i, i, i));
   }
 
   return a.exec();
}
 

Но listMyClassP придётся в любом случае чистить руками.
Например так:
Код
C++ (Qt)
   qDeleteAll(listMyClassP);
   listMyClassP.clear();
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
mutineer
Гость
« Ответ #3 : Июль 10, 2012, 10:41 »

Код:
void AddToListB(float x, float y, float z)
{
    MyClass myClassInstance(x, y, z);
    listMyClassP.push_back(&myClassInstance);
}

Это чушь и работает только чудом: myClassInstance удаляется при выходе из функции AddToListB и лист получает указатель, который указывает в стек туда, где был объект, а сейчас уже может быть что угодно
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Июль 10, 2012, 12:30 »

Наверное человек хочет сделать 2 QList - в одном сами данные, в другом указатели на них. Тогда так
Код
C++ (Qt)
listMyClass.push_back(myClassInstance(x, y, z));
listMyClassP.push_back(&listMyClass.back());
 
Т.е. в контейнер указателей нужно помещать адрес элемента уже занесенного в контейнер значений, Теперь если мы добавляем элементы адреса не меняются. Это будет работать если sizeof(myClassInstance) > sizeof(void *)

Примечания:

1) Хотя дословный перевод List = список, но по существу QList массив, а совсем не список.

2) Хранение простых структур как (x, y, z) в QList не запрещено но использует больше памяти чем QVector. Обычно выбор контейнера-массива определяется тем хотим ли мы иметь неизменный адрес элемента. Если да - QList, иначе QVector
Записан
CuteBunny
Гость
« Ответ #5 : Июль 10, 2012, 15:53 »

Либо как вариант использовать умные указатели:

Код
C++ (Qt)
 
class MyClass
{
private:
   float x, y, z;
 
public:
MyClass(): x(0.0), y(0.0), z(0.0) {};
       MyClass(float _x, float _y, float _z): x(_x), y(_y), z(_z) {};
~MyClass() {};
 
float GetX() {return x;};
void SetX(float _x) {x=_x;};
 
   //  ...
   //  ...
   //  ...
 
};
 
QList<MyClass> listMyClass;
QList<QSharedPointer<MyClass> > listMyClassP;
 
 
void AddToListA(float x, float y, float z)
{
   listMyClass.push_back(MyClass(x, y, z));
}
 
 
void AddToListB(float x, float y, float z)
{
   listMyClassP.push_back(QSharedPointer<MyClass>(new MyClass(x, y, z)));
}
 
 
int main(int argc, char *argv[])
{    
   for (int i = 0; i < 10; i++)
   {
       AddToListA(i, i, i);
       AddToListB(i, i, i);
   }
   return 0;
}
 
 
[/code=cpp]
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Июль 10, 2012, 19:48 »

Хотя человек спрашивал не об этом, но все же всегда полезно ну хотя бы "обращать внимание" на то а что из себя представляет элемент данных. Напр помещать в QList элемент (x, y, z) уже не очень хорошо, а "умный" указатель становится явно глупым будучи накрученным на каждую точку. Стандартные get/set также работают в минус если структура слишком мала и/или слишком конкретна как эта (x, y, z)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.135 секунд. Запросов: 23.