Верна ли ссылка из временной переменной?
Я сталкивался с ситуацией, когда возможность цепочки вызова метода для временной переменной была бы действительно полезна:
draw(Quad(0, 0, 1, 1).rotate(90)); // <-- .rotate() returns a Quad reference
struct Quad{
Quad(float x, float y, float width, float height){...}
Quad & rotate(float degrees){
...
return *this;
}
}
Тем не менее, я не уверен, что временная переменная останется в живых достаточно долго для draw()
функция, чтобы использовать это. Это безопасно сделать?
2 ответа
Это конкретное использование безопасно. Временный длится до конца полного выражения, которое его создает†; здесь полное выражение - это целое утверждение, включая вызов draw
,
В общем, эта картина может быть опасной. Следующее дает неопределенное поведение:
Quad & rotated = Quad(0, 0, 1, 1).rotate(90);
draw(rotated);
На мой взгляд, я бы предпочел, чтобы тип был неизменным; вместо вызова функции для изменения существующего объекта, вызовите const
функция для возврата нового объекта, оставляя существующий объект без изменений.
† Если оно не привязано непосредственно к ссылке, что увеличивает его время жизни, чтобы соответствовать ссылке. Это не применимо здесь, так как оно не связано напрямую.
Да, временный Quad
уничтожается в конце полного выражения ;
). Так что он еще жив, когда вы звоните rotate
на нем, и еще жив, когда вы звоните draw
с этим в качестве параметра.