crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> QString объект из функции.
Ponchikus
  опции профиля:
сообщение 19.1.2016, 15:32
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 21
Регистрация: 25.6.2015
Пользователь №: 4411

Спасибо сказали: 0 раз(а)




Репутация:   0  


Доброго времени суток, уважаемые форумчане. Очень интересует следующий вопрос.

QString returnStr()
{
QString string("a");

qDebug()<<&string;        // например адрес 0x111111

return string;
}

int main()
{
...
QString str=returnStr();
qDebug()<<&str;         //тот же адрес, 0x111111
...


Почему в этом случае у переменной "string" и у переменной "str" один и тот же адрес ???
Спасибо!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 19.1.2016, 17:24
Сообщение #2


Мастер
******

Группа: Модератор
Сообщений: 3293
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Это оптимизация такая: Return value optimization
Если поиграться с разными уровнями оптимизации, то скорее всего при -O0 должны быть разные адреса.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Ponchikus
  опции профиля:
сообщение 19.1.2016, 18:45
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 21
Регистрация: 25.6.2015
Пользователь №: 4411

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(ViGOur @ 19.1.2016, 17:24) *
Это оптимизация такая: Return value optimization
Если поиграться с разными уровнями оптимизации, то скорее всего при -O0 должны быть разные адреса.


Если я правильно понял, функция returnStr(), благодаря этой оптимизации (в которой локальная переменная "string" как я понял вообще отбрасывается), в неявной форме принимает примерно следующий вид:

QString returnStr()
{
return QString("a");
}


Так ?

Спасибо за Ваш ответ.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 19.1.2016, 19:46
Сообщение #4


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Цитата
принимает примерно следующий вид

Нет, RVO, означает что не создается временный объект для хранения значения, возвращаемого из функции.
Локальная переменная не отбрасывается, иначе бы qDebug() ничего не печатал бы.

Немного переделанный пример из википедии:
void returnStr(QString * _hiddenAddress) {
  *_hiddenAddress = "a";
}


Сообщение отредактировал lanz - 19.1.2016, 19:46
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Ponchikus
  опции профиля:
сообщение 19.1.2016, 21:34
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 21
Регистрация: 25.6.2015
Пользователь №: 4411

Спасибо сказали: 0 раз(а)




Репутация:   0  


lanz, благодарю за пояснения, только всеравно не ясно, как у локальной переменной созданной в функции и у переменной созданной в другой функции может быть один и тот же адрес. Это странно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 20.1.2016, 8:03
Сообщение #6


фрилансер
******

Группа: Участник
Сообщений: 2906
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Ponchikus, ты выводишь адрес локальной переменной, которая уже будет уничтожена по выходу из функции. Поэтому адрес вполне уже может использоваться под новые нужды. Значение, которая вернула функция, используется в конструкторе при создании нового объекта (QString str), для которого и был использован уже освободившийся адрес


кстати, вот так

QString str;
str=returnStr();
qDebug()<<&str;



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

Сообщение отредактировал Алексей1153 - 20.1.2016, 8:16
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 20.1.2016, 10:15
Сообщение #7


Мастер
******

Группа: Модератор
Сообщений: 3293
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Ну смотри, если бы все это отрабатывало без оптимизации, то вызовы были бы примерно такие:
Конструктор QString             // Создаётся локальный объект QString
Конструктор копий QString  // Копируется временный объект возвращенный из returnStr
Деструктор QString              // Удаляется локальный объект QString созданный в returnStr
...
Деструктор QString              // Удаляется локальный объект QString базовый
При оптимизации буду вызваны только Конструктор и Деструктор, что-то вроде:
QString *returnStr()
{
    return new QString("a");
}
int main()
{
    QString *str=returnStr();
}
Но со своим выделением памяти и своим сборщиком мусора

Для того, чтобы изучить как и что работает ты можешь создать обычный класс CClass например и сделать для него все то же самое поэкспериментировав с ключами оптимизации.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Ponchikus
  опции профиля:
сообщение 20.1.2016, 13:42
Сообщение #8


Студент
*

Группа: Участник
Сообщений: 21
Регистрация: 25.6.2015
Пользователь №: 4411

Спасибо сказали: 0 раз(а)




Репутация:   0  


ViGOur, спасибо, теперь более понятно. Попробовал с тестовым классом поэкспериментировать, в самом деле получается что-то подобное тому, что Вы и описали. Всем спасибо за ответы !
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 27.1.2021, 22:43