Переместить значение из локального стека в кучу? (C ++) - PullRequest
23 голосов
/ 27 сентября 2011

Как я могу взять результат объекта как значение из вызова метода и поместить его в кучу?

Например:

Метод Qt QImage::scaledToWidth возвращает копию объекта QImage.

Прямо сейчас я делаю:

QImage *new_img_on_heap = new QImage(old_imgage_on_heap->scaledToWidth(2000));

Это единственный способ?Похоже, у меня возникают проблемы с созданием 3-го совершенно нового объекта, когда у меня уже есть идеально хороший объект в стеке.

Причина, по которой я хочу поместить его в кучу, заключается в том, что настоящий QImageбольшой, и я хочу, чтобы он пережил время жизни текущего метода.Я собирался поместить указатель на него в поле моего класса.

Я знаю, что QImage имеет своего рода неявный обмен данными, но я не совсем понимаю, как это работает под капотом.,Кроме того, я хотел знать общее решение, если мне когда-нибудь понадобится использовать объекты, которые не так хорошо спроектированы, как у Qt.

Ответы [ 3 ]

14 голосов
/ 27 сентября 2011

Объект идентифицируется по его адресу. Если ты хочешь это в другом адрес, вы должны построить новый; Вы не можете перемещать объекты. (Четное в C ++ 11 новый & ldquo; move & rdquo; семантика на самом деле не двигать объект; они обеспечивают оптимизированный способ изменения его стоимости, если вы знаете что вам не понадобится значение, откуда вы его перемещаете.)

5 голосов
/ 27 сентября 2011

Во-первых, в большинстве случаев вы предпочитаете стек куче.

Во-вторых, когда вы размещаете объекты в куче, вы должны обернуть необработанный указатель в некоторый управляемый объект, который находится в стеке. Если ни для чего другого, сделайте это ради безопасности исключений.

В-третьих, объекты Qt обычно делают именно это , т.е. нет никакого преимущества в написании new QImage или new QMap<int> и т. Д.

Тем не менее, правильный способ перемещения объекта без кучи в кучу - это сказать

new ObjectType (old_instance)

Если вы делаете это с временным объектом, таким как

new ObjectType (create_object ())

тогда, вероятно, удалит лишнюю копию (ссылка не работает для меня - кэширована )

0 голосов
/ 27 сентября 2011

Так как метод

QImage QImage :: scaledToWidth (int width, Qt :: TransformationMode mode = Qt :: FastTransformation) const

не возвращает адрес QImage (т.е. QImage & ....), чем, я думаю, вам не повезло. Вы застряли с копией. Если вы не хотите перекомпилировать библиотеки QT, чтобы изменить сигнатуру этой функции, чтобы она не возвращала копию.

Что плохого в том, что этот объект все равно находится в стеке?

...