Перейти к содержимому
Теория · Классы и ООП · урок 5 из 15

const-методы

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

У класса, однако, есть методы, и одни только читают поля, а другие их меняют. Какие из них можно вызвать у объекта под стеклом? Компилятор решает это по объявлению метода, а не по его телу:

C++
#include <iostream>

class Temperature {
public:
    Temperature(int celsius) : celsius_(celsius) {}
    int celsius() const { return celsius_; }
    void warm() { ++celsius_; }
private:
    int celsius_;
};

int main() {
    const Temperature t(20);
    std::cout << t.celsius() << '\n';  // 20
}

const-методы

У константного объекта, как и через ссылку const T&, можно вызвать только const-методы. Это методы со словом const после списка параметров, как int celsius() const.

Слово const здесь — обещание: метод не меняет объект. Компилятор держит его так:

  • внутри const-метода объект тоже константный, и присвоить значение полю там нельзя;
  • исключение — поле, объявленное со словом mutable: его можно менять и в const-методе. Пример — счётчик вызовов, который не меняет смысла объекта.

Для const Temperature t(20); вызов t.celsius() компилируется, а t.warm() — нет: warm объявлен без const, и компилятор не пускает его к экспонату.

Поэтому метод, который только читает поля, объявляют const. Его можно вызвать для любого объекта, и константного, и обычного.

Зачем это нужно? Большие объекты передают в функции по константной ссылке const T&, чтобы не копировать их. Внутри такой функции объект — тот же экспонат под стеклом. Если методы чтения объявлены без const, функция не сможет вызвать даже их.

Этот вопрос часто задают на собеседовании: что значит const после списка параметров. Ответ: метод не меняет объект, для которого его вызвали.

Частая ошибка

Метод только читает поле, но объявлен без const:

C++
class Temperature {
public:
    Temperature(int celsius) : celsius_(celsius) {}
    int celsius() { return celsius_; }

private:
    int celsius_;
};

int twice(const Temperature& t) {
    return t.celsius() * 2;  // ✗
}
TEXT
error: 'this' argument to member function 'celsius' has type 'const Temperature', but function is not marked const

Параметр t — константная ссылка, а celsius() не обещает оставить объект неизменным, поэтому вызов не компилируется. Добавьте const после списка параметров: int celsius() const.

Главное

  • У константного объекта и через const T& можно вызвать только const-методы.
  • const после списка параметров обещает, что метод не меняет объект.
  • Компилятор проверяет объявление метода, а не его тело.
  • Метод, который только читает поля, объявляйте const.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом