Должны ли классы, производные не от QObject, «всегда» помещаться в стек? - PullRequest
5 голосов
/ 05 августа 2010

Исходя из мира Symbian, я привык максимально использовать кучу, чтобы избежать нехватки стекового пространства, особенно при обработке дескрипторов. Производные классы CBase всегда динамически размещались в куче, так как в противном случае их переменные-члены оставались бы неинициализированными. Применяется ли то же соглашение к классам, производным от QObject?

В Qt, кажется, принято помещать, например, QString в стек. Содержимое строки помещается в кучу, в то время как QString действует как контейнер в стеке, или все помещается в стек?

Ответы [ 2 ]

10 голосов
/ 05 августа 2010

Как сказал sje397: идиоматично помещать QString и контейнеры в стек, так как они неявно используются совместно.Их внутренности (pimpl идиома "d" указатель) создаются в куче.Также нет смысла создавать сам объект в куче.Просто возникают проблемы с управлением памятью, и вы теряете предполагаемые свойства копирования при записи при передаче указателей на строки / контейнеры.

QObjects с другой стороны, вы хотите создать в куче почти во всех случаяхиначе они бы сразу же были уничтожены.Они не могут быть скопированы или назначены (хорошо, это можно применить для собственных подклассов, но семантика QObject тогда нарушена), и обычно они должны выживать в теле метода, в котором они созданы. Исключение составляет QDialog, который часто создается в стеке, за которым следует QDialog::exec, который блокируется до закрытия диалога.Но даже это строго говоря небезопасно, поскольку внешние события (вызовы RPC, фоновые операции) могут привести к удалению диалога его родителем (если сам родитель удален) до возврата exec.Тогда создание диалогового окна в стеке приведет к двойному удалению при размотке стека -> сбой.

1 голос
/ 05 августа 2010

QString и многие другие классы Qt используют неявный обмен данными . Это означает, что память обычно выделяется в куче.

...