Это не что-то, о чем я когда-либо волновался бы. Я заботился бы о ясности и безопасности попытки... наконец о блоке по касающемуся сам тем, насколько "дорогой" это.
я лично не использую 286, ни делает любого использующего .NET или Java также. Движение. Беспокойство о записи хорошего кода, который будет влиять на Ваших пользователей и других разработчиков вместо базовой платформы, которая хорошо работает для 99,999999% людей, использующих его.
Это, вероятно, не очень полезно, и я не означаю быть уничтожающим, но просто выделяющаяся перспектива.
1. Правильная ли реализация
getA1 ()
? Я считаю, что это неверно, так как он возвращает адрес локальной переменной или временный.
Единственная версия getAx ()
, которая правильна в вашей программе, - это getA3 ()
. У обоих остальных есть неопределенное поведение, независимо от того, как вы их используете позже.
2. Какое из утверждений в main (1,2,3) приведет к неопределенному поведению?
В каком-то смысле ни одно из них. Для 1 и 2 неопределенное поведение является результатом тел функций. В последней строке newA3
должна быть ошибка компиляции, поскольку вы не можете привязать временную ссылку к неконстантной ссылке.
3. В
const A & newA1 = getA1 ();
стандартно гарантирует, что временная привязка кconst
ссылка не будет уничтожена, пока ссылка не выйдет за рамки?
Нет. Ниже приведен пример этого:
A const & newConstA3 = getA3 ();
Здесь getA3 ()
возвращает временное значение, и время жизни этого временного объекта теперь привязано к объекту newConstA3
. Другими словами, временное будет существовать до тех пор, пока newConstA3
не выйдет из области видимости.
Я думаю, что основная проблема в том, что вы вообще не возвращаете временные, вы должны
return A(5);
, а не
A a(5);
return a;
. В противном случае вы возвращаете адрес локальной переменной, а не временную. А временная ссылка на константу работает только для временных.
Я думаю, что это объясняется здесь: временная ссылка на константу
Q1: Да, это проблема, см. Ответ на Q2.
Q2: 1 и 2 не определены, поскольку они относятся к локальным переменным в стеке getA1 и getA2. Эти переменные выходят из области видимости и больше не доступны, и, что еще хуже, они могут быть перезаписаны, поскольку стек постоянно меняется. getA3 работает, поскольку копия возвращаемого значения создается и возвращается вызывающей стороне.
Q3: Нет такой гарантии, чтобы увидеть ответ на Q2.
Если вы скомпилируете это на VC6, вы получите это предупреждение
****** Предупреждение компилятора (уровень 1) C4172 адрес возврата локальной переменной или временной Функция возвращает адрес локальной переменной или временного объекта. Локальные переменные и временные объекты уничтожаются при возврате функции, поэтому возвращенный адрес недействителен. ******
Во время тестирования этой проблемы я обнаружил интересную вещь (данный код работает в VC6):
class MyClass
{
public:
MyClass()
{
objID=++cntr;
}
MyClass& myFunc()
{
MyClass obj;
return obj;
}
int objID;
static int cntr;
};
int MyClass::cntr;
main()
{
MyClass tseadf;
cout<<(tseadf.myFunc()).objID<<endl;
}