LINUX.ORG.RU

внутреннее устройство контейнеров Qt

 , ,


0

3

вопросы:
1) где располагаются данные (положим, валидные указатели), забубененные в контейнер, находящийся в стеке и целесообразно ли размещать сами контейнеры в динамической памяти (плюсы и минусы обоих вариантов).
2) есть ли принципиальное отличие (по данному критерию) контейнеров Qt от контейнеров STL

где располагаются данные (положим, валидные указатели), забубененные в контейнер, находящийся в стеке

сабж всё в куче хранит... от того где ты разместил контейнер это не зависит.

целесообразно ли размещать сами контейнеры в динамической памяти (плюсы и минусы обоих вариантов).

Там на стек всё-равно мало что ляжет, данные как не крути контейнеры кидают в кучу.

erfea ★★★★★ ()
Ответ на: комментарий от vladimirsmirnov9

Пожалуйста. ЗЫ вообще познакомься с кьютешными контейнерами поближе. Годная штука. Знают свой размер, легко передаются в аргументах. Есть замечательный QDataStream::setVersion( int v ), использование которого позволяет быть уверенным, что накидав в каком-нить Qt 4.2 в поток (скажем в файл) контейнеров, ты потом их таки прочитаешь в современном Qt 4.8. Ну и, конечно, годный foreach из коробки.

erfea ★★★★★ ()
Ответ на: комментарий от anonymous

кутешный foreach не рекомендуется использовать с std контейнерами.

А я рекомендовал, ага, прям раз эдак 20... не годный нынче анонимус пошёл, хреново вбрасывает...

erfea ★★★★★ ()
Ответ на: комментарий от wota

и какой другой компилятор ты используешь вместе с Qt?

Может похудеешь наконец?! Или мы на ЛОРе даем советы только как сделать программу собирающуюся исключительно на своём компе и своей версии компилятора. Попробуй хоть раздать людям исходник напичканый свежими фичами (ну или гнутыми хаками), гарантирую ты охренешь на чём люди компилируют.

erfea ★★★★★ ()
Ответ на: комментарий от erfea

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

wota ★★ ()
Ответ на: комментарий от Boy_from_Jungle

а что такого особенно в кутешном foreach?

Батхёрт вызывает у особо одарённых... А так годный макрос, удобен, задачу решает. ЗЫ решение из С++11, полюбас лучше, но использовать бездумно только для ССЗБ.

erfea ★★★★★ ()
Ответ на: комментарий от Boy_from_Jungle

Qt automatically takes a copy of the container when it enters a foreach loop. If you modify the container as you are iterating, that won't affect the loop. (If you do not modify the container, the copy still takes place, but thanks to implicit sharing copying a container is very fast.)

Since foreach creates a copy of the container, using a non-const reference for the variable does not allow you to modify the original container. It only affects the copy, which is probably not what you want.

http://qt-project.org/doc/qt-4.8/containers.html#the-foreach-keyword

seed_stil ★★ ()

2) есть ли принципиальное отличие (по данному критерию) контейнеров Qt от контейнеров STL

Контейнеры STL намного лучше оптимизированы по памяти и быстродействию. Быстродействие особенно заметно при разработке приложений обработки реального масштаба времени.

tekilla ()
Ответ на: комментарий от erfea

У него два недостатка. Первый состоит в том, что он копирует контейнер который обходит. Qt-шные контейнеры умеют COW, а контейнеры из STL - нет. Так что для них это вполне себе явное копирование. Кроме того изменить таким образом сам контейнер тоже не выйдет. Второй недостаток состоит в том, что это макрос и он считает что запятая это разделитель аргументов. Попробуй обойти например массив пар или что-то подобное.

KblCb ★★★★★ ()
Ответ на: комментарий от erfea

сабж всё в куче хранит... от того где ты разместил контейнер это не зависит.

А теперь назови один контейнер Qt, для которого это утверждение ложно.

annulen ★★★★★ ()
Ответ на: комментарий от wota

gcc, clang, icc, msvc - мало?

Не десктопом единым. Я вот например просто мечтаю избавиться от gcc 2.95 хотя бы в пользу 3.4 на одной из embedded-платформ...

annulen ★★★★★ ()
Ответ на: комментарий от KblCb

Попробуй обойти например массив пар или что-то подобное.

typedef. Хотя все равно костыль.

Кстати, даже с Qtшными контейнерами не стоит забывать про старые добрые итераторы

annulen ★★★★★ ()
Ответ на: комментарий от Boy_from_Jungle

а что такого особенно в кутешном foreach?

гугли «kde foreach don't suck» - найдешь статью где расписано, как его надо и как не надо использовать.

annulen ★★★★★ ()
Ответ на: комментарий от annulen

А теперь назови один контейнер Qt, для которого это утверждение ложно.

Либо их 0, либо строго больше 1.

anonymous ()
Ответ на: комментарий от KblCb

Qt-шные контейнеры умеют COW, а контейнеры из STL - нет.

COW - не всегда преимущество. Он приводит к дополнительным накладным расходам при каждом обращении (проверка, нужно ли делать detach). В Qt5 собирались лишить COW QVector.

annulen ★★★★★ ()

есть ли принципиальное отличие (по данному критерию) контейнеров Qt от контейнеров STL

1) STL-контейнеры обычно эффективнее, так как используют шаблонное метапрограммирование, допускающее широкие возможности оптимизации (которыми плохой компилятор может не воспользоваться)

2) STL-контейнеры имеют множество возмоджностей настройки, Qt-контейнеры практически не настраиваются.

3) Код с использованием STL может давать при компиляции бинарник большего размера из-за п. 1

4) Существует различные реализации STL, а Qt везде одинаков. Например, код, зависящий от ADL, компилирующийся с libstdc++, может не компилироваться с Apache STDCXX

5) Не все контейнеры STL имеют эквивалентные аналоги в Qt, и наоборот

6) STL последовательно применяет разделение контейнеров и алгоритмов, Qt - не всегда.

annulen ★★★★★ ()
Ответ на: комментарий от annulen

Не десктопом единым. Я вот например просто мечтаю избавиться от gcc 2.95 хотя бы в пользу 3.4 на одной из embedded-платформ...

почему сразу десктопом - сервером тоже, а что касается embedded-платформ, то там и libc + libstdc++ зачастую кастрированные, если вообще есть, это локальные проблемы тех, кто под них пишет, и эти проблемы у них всегда будут, причем у всех разные; так что повторюсь - единственно правильное решение писать по стандарту (если нет прямых ограничений), кому надо будет - пусть пинает авторов компиляторов, SDK, правит код и пр., т.к. проблема на его стороне, не надо ее перекладывать на остальных

wota ★★ ()
Ответ на: комментарий от annulen

Он «умно» их хранит. Либо на стеке, либо в куче:

template <class T, int Prealloc>
Q_INLINE_TEMPLATE QVarLengthArray<T, Prealloc>::QVarLengthArray(int asize)
    : s(asize) {
    if (s > Prealloc) {
        ptr = reinterpret_cast<T *>(qMalloc(s * sizeof(T)));
        Q_CHECK_PTR(ptr);
        a = s;
    } else {
        // char array[sizeof(qint64) * (((Prealloc * sizeof(T)) / sizeof(qint64)) + 1)];
        ptr = reinterpret_cast<T *>(array); 
        a = Prealloc;
    }
    if (QTypeInfo<T>::isComplex) {
        T *i = ptr + s;
        while (i != ptr)
            new (--i) T;
    }
}

anonymous ()
Ответ на: комментарий от annulen

Однако он не хранит в куче ВСЕ, поэтому я прав

Он хранит ВСЕ, но НЕ ВСЕГДА. :3

anonymous ()
Ответ на: комментарий от annulen

Q

спасибо. а что значит неглубокое копирование? допустим, объекты моего класса должны иметь доступ к контейнеру. я понимаю, что если я буду хранить указатель - то при замене контейнера на другой (если вдруг понадобится) нужно будет лишь переприсвоить указатель. но что произойдёт в такой ситуации:

class myClass {
   ...
public:
   void setList(QList<anotherClass*> &list) {
      List = list;
}
private:
   QList<anotherClass*> List;
}

...

QList<anotherClass*> list<<a1<<a2<<a3;
myClass *obj = new myClass();
obj->setList(list);
сходу ничего не нагуглил. контейнер list же в данном случае будет расположен в стеке - значит, супер-умные контейнеры Qt только лишь присвоят его адрес? а когда в таком случае он будет удалён? а если нет - то в чём суть неглубокого копирования? не понимаю

vladimirsmirnov9 ()
Ответ на: Q от vladimirsmirnov9
template <typename T>
Q_OUTOFLINE_TEMPLATE QList<T>::~QList()
{
    if (!d->ref.deref())
        free(d);
}

Деструктор уменьшает счетчик ссылок, а удаляет только последний экземпляр.

annulen ★★★★★ ()
Ответ на: комментарий от vladimirsmirnov9

Сам контейнер будет уничтожен, а его внутренний объект, содержащий данные - нет (до тех пор, пока на него ссылается хотя бы один объект контейнера)

annulen ★★★★★ ()
Ответ на: комментарий от vladimirsmirnov9

Только если твой локальный контейнер является копией глобального. В противном случае ещё как будет.

KblCb ★★★★★ ()

оффтопик:
кто-нибудь знает, как устроены внутренности QPixmap? где хранятся данные об изображении? подозреваю, что в куче, но хотелось бы убедиться

vladimirsmirnov9 ()
Ответ на: комментарий от anonymous

QPixmap & QPixmap::operator= ( const QPixmap & pixmap )

Assigns the given pixmap to this pixmap and returns a reference to this pixmap.
:)

vladimirsmirnov9 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.