Переместить значение из локального стека в кучу? (С++)
Как я могу взять результат объекта-значения из вызова метода и поместить его в кучу?
Например:
Метод Qt QImage::scaledToWidth
возвращает копию объекта QImage
.
Сейчас я делаю:
QImage *new_img_on_heap = new QImage(old_imgage_on_heap->scaledToWidth(2000));
Это единственный способ? Похоже, что это происходит из-за проблемы создания 3-го целого нового объекта, когда у меня уже есть хороший товар в стеке.
Причина, по которой я хочу положить его в кучу, состоит в том, что реальный QImage
большой, и я хочу, чтобы он пережил время жизни текущего метода. Я собирался наложить указатель на него в поле моего класса.
Я знаю, что QImage
имеет своего рода неявный обмен данными, но я не совсем понимаю, как он работает под капотом. Кроме того, я хотел бы знать общее решение, если мне когда-либо понадобится использовать объекты, которые не так хорошо разработаны как Qt.
Ответы
Ответ 1
Объект идентифицируется по его адресу. Если вы хотите это в другом
адрес, вы должны построить новый; вы не можете перемещать объекты. (Даже
с С++ 11, новая семантика "перемещения" фактически не перемещает
объект; они обеспечивают оптимизированный способ перемещения своей ценности, если вы знаете
что вам не понадобится значение, откуда вы его перемещаете.)
Ответ 2
Во-первых, вы должны предпочесть стек в кучу в большинстве случаев.
Во-вторых, когда вы выделяете объекты в куче, вы должны обернуть необработанный указатель в некоторый управляемый объект, который находится в стеке. Если ничего другого, сделайте это для безопасности исключений.
В-третьих, объекты Qt обычно делают именно это, то есть нет преимущества при написании new QImage
или new QMap<int>
и т.д.
Тем не менее, правильный способ перемещения объекта без кучи в кучу состоит в том, чтобы сказать
new ObjectType (old_instance)
Если вы делаете это с помощью временного объекта, например
new ObjectType (create_object ())
то это, вероятно, будет удалить дополнительную копию (ссылка для меня - cached)
Ответ 3
Так как метод
QImage QImage:: scaledToWidth (int width, Qt:: TransformationMode mode = Qt:: FastTransformation) const
не возвращает адрес QImage (т.е. QImage &....), чем я думаю, вам не повезло. Вы застреваете с копией. Если вы не хотите перекомпилировать библиотеки QT для изменения этой сигнатуры функции, чтобы она не возвращала копию.
Что плохого в том, что этот объект в стеке так или иначе?