Qubc
@Qubc
Ненавижу полисемию.

Почему у временного объекта можно вызывать non-const метод?

class X {
 int i;
public:
 X(int ii = 0);
 void modify();
};
X::X(int ii) { i = ii; }
void X::modify() { i++; }
X f5() {
 return X();
}
const X f6() {
 return X();
}
void f7(X& x) { // Pass by non-const reference
 x.modify();
}
int main() {
 f5() = X(1); // OK -- non-const return value
 f5().modify(); // OK
// Causes compile-time errors:
//! f7(f5());
//! f6() = X(1);
//! f6().modify();
//! f7(f6());
}


Компилятор создает временный объект после вызова f5, временные объекты имеют const квалификатор. Почему компилятор не ругается? Метод может изменить static переменную. Это какая-то оптимизация или привычка к которой все привыкли?
  • Вопрос задан
  • 176 просмотров
Решения вопроса 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
По поводу вызова неконстантных методов - а с чего вы взяли, что они не дожны быть возможны? Временные объекты не имеют const квалификаторов. Иначе нельзя было бы делать вещи типа SomethingBuilder().WithA().WithB().Finalize().

//! f6() = X(1);

Оператор присвоения требует Lvalue слева. Временный объект же - Rvalue. Eго можно ставить только справа от =. А не потому что у него const квалификатор.

Это сделано скорее всего потому, что, ну, нет же смысла перезаписывать временный объект. Он временный, к нему потом никак не обратиться.

//! f6().modify();

Вот тут попытка вызова неконстантного метода у константного (и временного - но это не важно) объекта.

//! f7(f5());

Видимо, это чтобы исключить некоторый класс ошибок. Если вы передаете в качестве неконстантной ссылки что либо, значит оно должно внутри менятся и снаружи эти изменения должны быть видны. Иначе можно было бы передавать по константной ссылке или по значению. Но вы передаете туда временный объект - его никак снаружи видно не будет. Он существует только в этой строчке. Поэтому в C++ нельзя инициализировать неконстантные lvalue ссылки через rvalue (временные объекты).
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
// Causes compile-time errors:
//! f7(f5());

Смотри, а ещё можно вот так сделать:
class X {
 int i;
public:
 X(int ii = 0);
 void modify();
 X& ref() {return *this;}
};
...
f7(f5().ref());
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы