Ключевое слово const в классах и функциях (С++)
Ключевое слово const в начале объявления метода/функции привязывает его к типу возвращаемого значения, т.е. говорит о том, что Вы возвращаете из метода константный объект.
const int Func(){//code};
Ключевое слово const в объектах классов
Объекты классов можно сделать константными (используя ключевое слово const). Инициализация выполняется через конструкторы классов:
const myClass A; // инициализация через конструктор по умолчанию
const myClass B(1, 10); // инициализация через конструктор с параметрами
В этом случае переменные становятся const –их невозможно изменить.
ВАЖНО!!! Константные объекты класса могут явно вызывать только константные методы класса.
Ключевое слово const в методах классов
В методах можно указывать ключевое слово const чтобы гарантировать что эти методы НЕ могут изменять значения внутри тела функции, поэтому они используются для работы с константными объектами класса.
Когда вы const используется в конце объявления метода, сам метод становится константным (ничего не изменяющим в объекте) и, как следствие, доступным для вызова через константные объекты.
Константный метод — это метод, который гарантирует, что не будет изменять объект или вызывать неконстантные методы класса (поскольку они могут изменить объект).
Рассмотрим синтаксис для константных методов.
int Func() const { return value; } // ключевое слово const находится после списка параметров, но перед телом функции
если метод определяется вне класса, то синтаксис следующий:
class c_A
{
public:
void Func() const; //прототип функции
};
int c_A::Func() const //определение функции
{
return value;
}
Примечания:
- Внутри константных методов можно вызывать только константные методы
Ключевое слово const является сигнатурой метода, т.е. можно создать 2 версии одного метода, константная версия функции будет вызываться для константных объектов, а неконстантная версия будет вызываться для неконстантных объектов:.
Например:
class cl_C
{
public:
//Код и перегрузка оператора =
const string Print() const {return this->Text } //для константных объектов
string Print() {return this->Text } //для НЕ константных объектов
private:
string Text;
};
Тогда при создании класса и вызове функций:
cl_C my_C;
my_C.Print()= "Hello!"; // вызывается неконстантный метод.
my_C.Print(); // вызывается константный метод.
Перегрузка метода и разделение его на константную и неконстантную версии обычно выполняется, когда возвращаемое значение должно отличаться по константности (когда требуется константа, и когда она не требуется).
В примере, приведенном выше, неконстантная версия Print() будет работать только с неконстантными объектами, но эта версия более гибкая, так как мы можем использовать её как для чтения, так и для записи Text (что мы и делаем, присваивая строку Hello!).
Но, когда мы не изменяем данные объекта класса, тогда вызывается константная версия Print().
Любой метод, который не изменяет данные объекта класса, должен быть const!
Существует понятие синтаксической и логической константности:
Ключевое слово const в объявлении метода гарантирует синтаксическую константность: константные методы не могут менять поля объекта (обеспечивается компилятором)
Логическая константность – нельзя менять те данные, которые определяют состояние объекта
Возможная ошибка:
Как известно массив – указатель на область в памяти, если он будет являться полем класса, то компилятор будет заботиться о нем как о указателе int* const например, но сами значения в массиве в константном методе можно будет изменять.
Ключевое слово mutable:
Иногда внутри константного метода нужно использовать не константные переменные, для этих полей используется ключевое слово mutable
например: mutable int Value;
Примечание: обычно с ключевым словом mutable используются различные счетчики (не влияющие на класс напрямую)