Случай 1: const
после подписи функции говорит, что функция не изменит объект.Таким образом, вы можете использовать его на const
объектах (или с указателем на const
или const
ссылкой).
Случай 2: const
перед именем функции действительно относится к типу возвращаемого значения.Вы совершенно правы: на практике это ничего не меняет для объекта, так как возвращение в этом фрагменте выполняется по значению, а это значение во временной переменной, которое не может быть изменено (например, ++
или --
будетв любом случае не будет действительным, потому что нет lvalue).
Случай 3: Значение const в возвращаемом типе будет более целесообразным при возврате указателя на const или ссылки на const.В этом случае это предотвратит изменение состояния объекта извне.
Вот краткая информация:
class foo {
public:
int A() const { // const function
return m_var;
}
int const B() { // non const function, but const return type
return m_var;
}
int const& C() const { // non const function, but const reference return type
return m_var;
}
private:
int m_var;
};
int main() {
const foo x{};
x.A(); // ok
//x.B(); // not ok -> function B() doesn't guarantee to leave x unchanged.
x.C(); // ok
const int& y = x.C(); // ok (y will not alter m_var.
//int& z = x.C(); // not ok since z is not const
return 0;
}
онлайн-демонстрация
Дело 4: (спасибо HolyBlackCat за указание на это).То, что не имеет значения для скаляров в случае 2, может иметь смысл для классов.Предположим, что m_var
будет иметь класс bar
:
class bar {
public:
void change_it() {}
void read_it() const {}
};
Тогда возвращаемое значение const будет иметь значение:
foo u{};
u.B(); // ok
u.B().read_it(); // ok
u.B().change_it(); // not ok because of constness of B().
онлайн-демонстрация