Какова цель const в этом?
const Object myFunc(){
return myObject;
}
Я только начал читать "Эффективный C++", и пункт 3 поддерживает это, а поиск в Google находит похожие предложения, но также и контрпримеры. Я не понимаю, как использование const здесь было бы предпочтительнее. Предполагая, что возврат по значению желателен, я не вижу причин защищать возвращаемое значение. Пример, приведенный для того, почему это может быть полезно, - это предотвращение непреднамеренного логического приведения возвращаемого значения. Реальная проблема заключается в том, что неявное приведение типа bool должно быть предотвращено с помощью ключевого слова manifest.
Использование const здесь предотвращает использование временных объектов без назначения. Поэтому я не мог выполнять арифметические выражения с этими объектами. Не похоже, чтобы когда-либо была полезна безымянная константа.
Что дает здесь использование const и когда это предпочтительнее?
РЕДАКТИРОВАТЬ: измените арифметический пример на любую функцию, которая изменяет объект, который вы, возможно, захотите выполнить перед назначением.
Ответ 1 · рейтинг 145 · Kerrek SB
В гипотетической ситуации, когда вы можете выполнить потенциально дорогостоящую неконстантную операцию над объектом, возврат по константному значению предотвратит случайный вызов этой операции для временного объекта. Представьте, что + вернуло неконстантное значение, и вы могли бы написать:
(a + b).expensive();
Однако в эпоху C++11 настоятельно рекомендуется возвращать значения как неконстантные, чтобы вы могли в полной мере использовать ссылки rvalue, которые имеют смысл только для непостоянных rvalue.
Подводя итог, можно сказать, что есть обоснование для такой практики, но по существу она устарела.
Ответ 2 · рейтинг 51 · Lightness Races in Orbit
Это красиво бессмысленно для вернуть значение const из функции.
сложно заставить это как-то повлиять на ваш код:
const int foo() {
return 3;
}
int main() {
int x = foo(); // copies happily
x = 4;
}
и:
const int foo() {
return 3;
}
int main() {
foo() = 4; // not valid anyway for built-in types
}
// error: lvalue required as left operand of assignment
Хотя вы можете заметить, что тип возвращаемого значения определяется пользователем:
struct T {};
const T foo() {
return T();
}
int main() {
foo() = T();
}
// error: passing ‘const T’ as ‘this’ argument of ‘T& T::operator=(const T&)’ discards qualifiers
сомнительно, что это кому-то выгодно.
Возврат ссылки отличается, но если Object не является параметром шаблона, вы этого не делаете.
Ответ 3 · рейтинг 8 · Grizzly
Это гарантирует, что возвращаемый объект (который в этот момент является RValue) не может быть изменен. Это гарантирует, что пользователь не может думать следующим образом:
myFunc() = Object(...);
Это бы хорошо работало, если бы myFunc возвращалось по ссылке, но почти наверняка является ошибкой, когда возвращается по значению (и, вероятно, не будет обнаружено компилятором). Конечно, в C++11 с его rvalue это соглашение не имеет такого большого смысла, как раньше, поскольку константный объект нельзя переместить, так что это может сильно повлиять на производительность.
Ответ 4 · рейтинг -3 · Steven Feldman
Его можно использовать как функцию-оболочку для возврата ссылки на закрытый постоянный тип данных. Например, в связанном списке у вас есть константы tail и head, и если вы хотите определить, является ли узел хвостовым или головным узлом, вы можете сравнить его со значением, возвращаемым этой функцией.
Хотя любой оптимизатор, скорее всего, все равно оптимизирует его...