Есть много ситуаций, в которых вы можете вернуть константный указатель или константный объект.Я не могу представить себе реальную ситуацию, когда вы хотите вернуть примитивный тип как const
.
Я не уверен, какой у вас вопрос, в названии, о котором вы говорите int* const
, но в примере кода у вас есть const int
.
Некоторые примеры (на C ++) следуют для различных комбинаций const
и T*
.
Указатель на const (примитивтип)
const int* someFuncion();
У вас есть указатель на константу, это означает, что вы можете изменить указатель, но вы не можете изменить указанный объект / значение.Обратите внимание, что someFunction()
не должен возвращать указатель (const
или нет) на переменную, выделенную в стеке.Я предполагаю, что указатель действителен.Например:
const int* value = someFunction();
// Next line is valid, value will hold a new pointer
value = anotherFunction();
// Next line is not valid, pointed value cannot be changed
*value = 10;
Указатель на const (объект)
const T* someFunction();
У вас есть указатель на константу.Это означает, что вы можете изменить указатель так, чтобы он указывал на другой объект, но вы не можете изменить состояние указанного объекта.Это не означает, что вы не можете использовать этот объект, только то, что объект является const, тогда вы можете использовать только его методы, помеченные как const, читать его поля и записывать его изменяемые поля.Константный метод определяется как:
void method() const;
Он может иметь любой тип возвращаемого значения и любой параметр, суть в том, что он помечен модификатором const
.Это означает, что он не изменит состояние объекта (опять-таки, за исключением mutable
объектов).
Теперь приведен пример с T
, объявленным как:
class T
{
public:
void dump() const
{
// Dump the value to console, for example
}
void increaseValue()
{
++m_value;
}
private:
int m_value;
};
Представьте себенаписать следующий код:
const T* value = someMethod();
// Next line is valid, value will hold a new pointer
value = anotherMethod();
// Next line is not valid, we cannot change the object state
value->increaseValue();
// Next line is valid, we do not change the object state
value->dump();
Указатель константы (тип примитива)
int* const someFunction();
У вас есть указатель константы, это означает, что вы можете изменить указанное значение, но вы не можете назначить другую ячейку памятик самому указателю.Например:
int* const value = someFunction();
// Next line is not valid, value cannot be changed
value = anotherFunction();
// Next line is valid, you can change the variable pointed by value
*value = 10;
Указатель константы (объект)
T* const someFunction();
У вас есть указатель константы, это означает, что вы можете изменить состояние указанного объекта, но вы не можете назначить другую ячейку памяти длясам указательНапример:
T* const value = someFunction();
// Next line is not valid, value cannot be changed
value = anotherFunction();
// Next lines are both valid, we can do whatever we want with the object
value->increaseValue();
value->dump();
Указатель константы на постоянную
const int* const someFunction();
Это сочетание предыдущих объявлений.Все (ограничительные) правила, описанные выше, действительны.Это означает, что вы не можете изменить указатель и не можете изменить указанное значение.
Примечания
Модификатор const
не ограничен для использования с указателями и возвращаемым значением функций.Например:
// PI value cannot be changed
const int PI = 3.14f;
// I have a pointer to a constant value
const* int pPI = Π
// I have a constant pointer to a constant value, note that
const* int const pPI2 = Π
Помните, что модификатор const
всегда можно удалить, используя приведение в стиле C или const_cast
.
Выводы
Итак,Возвращаясь к вашему вопросу, полезна ли функция с const int
возвращаемым значением?
Если это указатель, мой ответ - да , даже если его можно удалить с помощью приведения:цель const
состоит в том, чтобы сообщить намерения (избавляя вас от глупых ошибок, которые трудно найти), чтобы больше вашей функции сообщалось и лучше ее использовали.Обновляя это из вашего последнего примера, я отвечу да , используйте const везде, где это возможно.Тот, кто назовет ваш код, поблагодарит вас (и вы сделаете это сами).
Если это просто const int
(или другой примитивный тип), может быть очень редко вы пишете что-то подобное,Очень часто они являются просто промежуточными результатами длинных вычислений, тогда их бесполезно объявлять как const
(примитивные типы не изменятся, но будут объединены для создания нового значения).Однако обратите внимание, что если имеет смысл объявить их как const
, то вы должны сделать это.Я предполагаю, что более распространено видеть постоянный тип примитива, объявленный как локальная переменная (опять же, чтобы убедиться, что он не будет изменен по ошибке)Например:
// This local variable cannot be modified
const int rate = (calculateX() + calculateY()) / calculateRateFactor();
Или в функциях, почему бы и нет?Если вы всегда используете это правило (const
, если его не нужно менять), вы увидите на лету, когда параметр не const
, тогда вы поймете, что вы его где-то измените (возможно, смаленький, скрытый, симпатичный ++
на самом правильном символе вашего экрана).
// With this prototype I'm sure I won't change a or b by mistake inside
// the function body.
int someFunction(const int a, const int b);
Для объектов, я думаю, еще более распространенным является использование модификатора const (поскольку тип возвращаемого значения const T
имеет смысл очень часто), например:
// This object cannot be changed, just moved all around
const order* getNextOrderToStore();
Тема не закончена, конечно, из-за псевдонимов, непостоянных переменных, перегрузки операторов и различий между C и C ++ ...