Важная информация
Показано с 1 по 8 из 8

Тема: Возврат ссылки на временный объект в С++

  1. #1 Возврат ссылки на временный объект в С++ 
    Профи Аватар для Сионист
    Регистрация
    21.01.2016
    Адрес
    Галактика Млечный Путь
    Сообщений
    509
    Сказал(а) спасибо
    11
    Поблагодарили 21 раз(а) в 20 сообщениях
    C++ Code:
    1. const TQuaternion &Invert ()
    2. {
    3. GLdouble Module=abs(*this);
    4. return TQuaternion(ScalarPart/Module, T3DDescartesVector(VectorPart.x/Module, VectorPart.y/Module, VectorPart.z/Module));
    5. }
    Имеет ли здесь место возврат ссылки на не существующую величину?
    Последний раз редактировалось Сионист; 08.02.2016 в 09:37.
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на си.
    Ответить с цитированием  
     

  2. #2  
    Профи Аватар для rrrFer
    Регистрация
    01.08.2013
    Сообщений
    561
    Сказал(а) спасибо
    34
    Поблагодарили 248 раз(а) в 164 сообщениях
    Тут создается временный объект:
    C++ Code:
    1. (ScalarPart/Module, T3DDescartesVector(VectorPart.x/Module, VectorPart.y/Module, VectorPart.z/Module))

    Ты возвращаешь ссылку на него, но при выходе из области видимости вызывается деструктор объекта и выходит, что ты возвращаешь ссылку на мусор.
    [Ссылки могут видеть только зарегистрированные пользователи. ] // программирование на Prolog, Erlang, C++
    Ответить с цитированием  
     

  3. Пользователь сказал cпасибо:

    >Quiet Snow< (08.02.2016)

  4. #3  
    Профи Аватар для Сионист
    Регистрация
    21.01.2016
    Адрес
    Галактика Млечный Путь
    Сообщений
    509
    Сказал(а) спасибо
    11
    Поблагодарили 21 раз(а) в 20 сообщениях
    Константность не спасает?
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на си.
    Ответить с цитированием  
     

  5. #4  
    Профи Аватар для rrrFer
    Регистрация
    01.08.2013
    Сообщений
    561
    Сказал(а) спасибо
    34
    Поблагодарили 248 раз(а) в 164 сообщениях
    Нет. В той строке в любом случае создается временный объект.
    Не спасет даже если объект будет создан в области видимости функции, например так:
    C++ Code:
    1.     const TQuaternion &Invert ()
    2.     {
    3.      GLdouble Module=abs(*this);
    4.      TQuaternion obj = TQuaternion(ScalarPart/Module, T3DDescartesVector(VectorPart.x/Module, VectorPart.y/Module, VectorPart.z/Module))
    5.      return obj;
    6.     }

    Тут запись идет в локальную переменную, но при выполнении return для всех локальных переменных вызываются деструкторы и по адресу, который ты попытаешься вернуть будет находиться уже мусор. Спасти может использование указателя, или умного указателя.
    [Ссылки могут видеть только зарегистрированные пользователи. ] // программирование на Prolog, Erlang, C++
    Ответить с цитированием  
     

  6. Пользователь сказал cпасибо:

    >Quiet Snow< (08.02.2016)

  7. #5  
    Профи Аватар для Сионист
    Регистрация
    21.01.2016
    Адрес
    Галактика Млечный Путь
    Сообщений
    509
    Сказал(а) спасибо
    11
    Поблагодарили 21 раз(а) в 20 сообщениях
    Указатель то как раз не уместен, тем более указатель для глупых. Получается, что надо вернуть просто объект. А из оператора сложения можно возвращать ссылку? А из составного оператора сложения и присваивания? Как? Кстати, указатель на локальный объект точно также не валиден.
    Последний раз редактировалось Сионист; 09.02.2016 в 12:01.
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на си.
    Ответить с цитированием  
     

  8. #6  
    Профи Аватар для rrrFer
    Регистрация
    01.08.2013
    Сообщений
    561
    Сказал(а) спасибо
    34
    Поблагодарили 248 раз(а) в 164 сообщениях
    А из оператора сложения можно возвращать ссылку? А из составного оператора сложения и присваивания?
    Я тебе уже написал, что ссылку на локальный или временный объект возвращать бессмысленно.
    Указатель возвращать можно, а умный указатель - еще и безопасно. С обычным указателем может быть проблема если ты будешь использовать функцию так foo(bar()). Ну потому что будет утечка памяти, а если речь идет об операторах - то таки да, это происходит постоянно, хотя это и нарушает закон Деметры.

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

    Получается, что надо вернуть просто объект.
    Так и надо сделать, при этом компилятор может как провести оптимизацию возвращаемого значения (он не будет просто вызывать деструктор локального объекта), так и вызвать конструктор копирования, а затем вызвать деструктор для старого объекта - стандарт это не прописывает. Когда я гонял такие примеры - почти всегда вызывался конструктор копирования, поэтому надеяться на компилятор тут особо не надо.
    [Ссылки могут видеть только зарегистрированные пользователи. ] // программирование на Prolog, Erlang, C++
    Ответить с цитированием  
     

  9. Пользователь сказал cпасибо:

    Free Admin (10.02.2016)

  10. #7  
    Профи Аватар для Сионист
    Регистрация
    21.01.2016
    Адрес
    Галактика Млечный Путь
    Сообщений
    509
    Сказал(а) спасибо
    11
    Поблагодарили 21 раз(а) в 20 сообщениях
    Я тебе уже написал, что ссылку на локальный или временный объект возвращать бессмысленно.
    Где здесь:
    C++ Code:
    1. TQuaternion &operator += (const TQuaternion &Right)
    2. {
    3.   ScalarPart  +=Right.ScalarPart;
    4.   VectorPart.x+=Right.VectorPart.x;
    5.   VectorPart.y+=Right.VectorPart.y;
    6.   VectorPart.z+=Right.VectorPart.z;
    7.   return *this;
    8. }
    возврат ссылки на что то локальное?
    C++ Code:
    1. Указатель возвращать можно, а умный указатель - еще и безопасно.
    Указатель на локальный объект не валиден по причине уничтожения объекта деструктором, а указатель для глупых вообще не должен существовать.
    Я предлагаю динамически память выделать.
    Ну так динамическая память сама по себе, а возврат указателя сам по себе. На неё тоже можно возвращать ссылки. Например, сделать в программе модуль со static-указателем, а в функциях этого модуля выделять и освобождать память по этому указателю и возвращать на неё ссылки. Другое дело, что так делать не надо. Но можно.
    Последний раз редактировалось Сионист; 13.02.2016 в 09:51.
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на си.
    Ответить с цитированием  
     

  11. #8  
    Профи Аватар для Сионист
    Регистрация
    21.01.2016
    Адрес
    Галактика Млечный Путь
    Сообщений
    509
    Сказал(а) спасибо
    11
    Поблагодарили 21 раз(а) в 20 сообщениях
    Цитата Сообщение от rrrFer Посмотреть сообщение
    Так и надо сделать, при этом компилятор может как провести оптимизацию возвращаемого значения (он не будет просто вызывать деструктор локального объекта), так и вызвать конструктор копирования, а затем вызвать деструктор для старого объекта - стандарт это не прописывает. Когда я гонял такие примеры - почти всегда вызывался конструктор копирования, поэтому надеяться на компилятор тут особо не надо.
    Так и сделал в сочетании с подсказкой из другой темы. Тест показал, что ни конструктор копий, ни перемещающий конструктор не вызывается, а вызывается перемещающий оператор присваивания, а потом деструктор.
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на си.
    Ответить с цитированием  
     

Информация о теме
Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Ответов: 0
    Последнее сообщение: 18.05.2015, 14:00
  2. Полезные ссылки
    от Free Admin в разделе Юридические вопросы
    Ответов: 1
    Последнее сообщение: 05.09.2014, 15:02
  3. Недорогие трастовые ссылки !
    от Ruplex в разделе Ссылки - обмен, покупка, продажа
    Ответов: 0
    Последнее сообщение: 01.08.2014, 19:34
  4. Ссылки с блога программиста
    от rrrFer в разделе Ссылки - обмен, покупка, продажа
    Ответов: 0
    Последнее сообщение: 01.05.2014, 07:02
  5. Ссылки покупка
    от Emily в разделе Ссылки - обмен, покупка, продажа
    Ответов: 1
    Последнее сообщение: 26.02.2013, 13:55
Ваши права
  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •