Время жизни временных объектов продолжается до полной длины выражения, в котором оно было создано при использовании without references
,
Учтите следующее:
class My
{
int i;
public:
void increment()
{
i++;
}
};
My withOutConst()
{
return My();
}
const My withConst()
{
return My();
}
int main()
{
My ob;
withOutConst().increment(); // Case 1
withConst().increment(); // Case 2
return 0;
}
Как я понимаю, компилятор создает temporary
объект (типа const My
) удерживать возвращаемое значение в вышеуказанных случаях.
И я пытаюсь изменить временный объект.
(1)
Компилирует нормально и
(2)
Приводит к ошибке времени компиляции с ошибкой:
error: passing 'const My' as 'this' argument of void My::increment() discards qualifiers
Это значит в основном this
имеет тип My
и не const My
как это называется для non-const
функция.
Мой вопрос:
Я пытаюсь изменить временный объект типа const My
позвонив non-const
функция-член.
Тогда почему я не получаю ту же ошибку в случае (1), потому что я работаю над объектом типа const My
в обоих случаях.
Я понимаю, что это связано с return type
функций, но не в состоянии полностью понять, потому что в конце все сводится к функции (void My::increment()
) который пытается изменить временные типы const My
в обоих случаях.
Временный имеет тип, этот тип может быть константным и неконстантным. Вы можете вызывать неконстантную функцию-член только для неконстантного объекта. withOutConst()
привести к временному типу My
, withConst()
дает временный тип const My
,
Может быть, у вас есть ошибочное мнение, что временное всегда const
? Если это так, то это неправильно.
Тогда почему я не получаю ту же ошибку в случае (1), потому что я работаю над объектом типа const My в обоих случаях.
Это просто неправда.
My withOutConst()
{
return My();
}
const My withConst()
{
return My();
}
withOutConst
возвращает объект типа My
, в то время как withConst()
возвращает объект типа const My
, Хотя в обоих случаях вы используете их как временные, их основной тип My
а также const My
точно так, как закодировано в сигнатурах функций.
Временный объект не должен быть постоянным.
Как я понимаю, компилятор создает временный объект (типа
const My
) удерживать возвращаемое значение в вышеуказанных случаях.
Нет. Возвращаемое значение withOutConst()
не является const
, так как вы не объявили это const
, Наблюдаемое поведение следует из этого.
Вы можете запутать существо const
с тем, чтобы быть Rvalue. Во многих ситуациях Rvalue не может быть изменено; но ты Можно вызовите непостоянную функцию-член на одном.
Если это упрощенная версия того, что вы пытаетесь сделать в более сложной кодовой базе, где вы все еще хотите использовать какой-то счетчик для объекта const, то вам нужно пометить переменную «i» как «изменяемый» ». Вот так:
class My
{
mutable int i;
public:
void increment()
{
i++;
}
};