<MyRusakov.ru />

Профессия Web-разработчик

Профессия Web-разработчик

Этот комплект за 8 месяцев превратит Вас в Web-разработчика с нуля. Учиться достаточно 1 час в день.

Начнёте Вы с HTML, CSS и вёрстки сайтов. Потом перейдёте к программированию и JavaScript. Затем изучите PHP, MySQL, SQL, Python. Изучите Web-фреймворки Laravel и Django. Создадите 5 своих сайтов для портфолио.

Комплект содержит:

- 540 видеоуроков

- 110 часов видео

- 1205 заданий для закрепления материала из уроков

- 5 финальных тестов

- 7 сертификатов

- 12 Бонусных курсов

Подробнее
Подписка

Подпишитесь на мой канал на YouTube, где я регулярно публикую новые видео.

YouTube Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Какая тема Вас интересует больше?

const в C++: понятное руководство по константности (const correctness) с примерами

const в C++: понятное руководство по константности (const correctness) с примерами

Запрос «const в C++» — один из самых частых у начинающих. Константность (const correctness) помогает сделать код безопаснее: защищает от случайной модификации данных, упрощает оптимизацию и улучшает читаемость API. Ниже — практическое руководство с примерами и советами для реальных проектов.

Что такое const в C++

Ключевое слово const делает объект неизменяемым в пределах области видимости. Примеры:

const int a = 10;        // a нельзя изменить
int const b = 20;        // одинаково с const int b

// Важно: const влияет на тип.
// top-level const — константность самого объекта;
// low-level const — константность того, на что указывает указатель/ссылка.

const и указатели: частые вопросы

Правило чтения: const «приклеен» к тому, что справа. Если справа ничего — смотрим слева.

int x = 1, y = 2;

const int* p1 = &x;   // pointer to const int (нельзя менять *p1, но можно p1)
int* const p2 = &x;   // const pointer to int (нельзя менять p2, но можно *p2)
const int* const p3 = &x; // const pointer to const int

*p1 = 42;   // ОШИБКА: *p1 — const
p1 = &y;    // OK

*p2 = 42;   // OK
p2 = &y;    // ОШИБКА: p2 — const

Ссылки всегда «константа-ссылка» (их нельзя переназначить), поэтому чаще пишут const T& для «только чтения» без копирования.

Константные методы и перегрузка по const

Метод с суффиксом const обещает не менять логическое состояние объекта (все поля, кроме помеченных как mutable).

struct Vec2 {
    double x{0}, y{0};

    double length() const {          // метод "только чтение"
        return std::sqrt(x*x + y*y);
    }

    void setX(double nx) { x = nx; } // изменяет объект
};

void demo() {
    const Vec2 v{3, 4};
    double L = v.length(); // OK
    // v.setX(10);         // ОШИБКА: метод не const
}

Можно перегружать методы по константности — удобно, когда для const-объекта возвращаем "чтение", а для неконстантного — "чтение+запись":

class Buffer {
    std::vector<int> data;
public:
    const int& operator[](size_t i) const { return data[i]; }
    int&       operator[](size_t i)       { return data[i]; }
};

void use(Buffer& b, const Buffer& cb) {
    int a = cb[0];   // возвращает const int&
    b[0] = 42;       // возвращает int& — можно менять
}

Параметры и возвращаемые значения

  • Мелкие типы (int, double, enum, указатели) передавайте по значению.
  • Крупные объекты — по const T& для избежания копирования.
  • Возвращать по значению — нормально; добавлять const к возвращаемому значению, как правило, бессмысленно.
// Хорошо: без лишних копий и с ясной семантикой
std::string_view Find(const std::string& s, char ch);

// Избыточно: const при возврате по значению не даёт пользы
const std::string MakeName(); // лучше просто std::string

Если нужна «глубокая» неизменяемость результата — возвращайте const T& только если гарантируете время жизни объекта (часто это член класса или статик).

const и STL: итераторы и диапазоны

Используйте const-итераторы и cbegin/cend для обхода без модификации:

std::vector<int> v{1,2,3};

for (auto it = v.cbegin(); it != v.cend(); ++it) {
    // *it — const int&
}

for (const auto& value : v) { // range-based for + const auto&
    // value — const int&
}

mutable и const_cast: когда уместно

Иногда «константный» метод хочет кэшировать результат. Для этого есть mutable — поле можно менять даже в const-методе. Делайте так только для прозрачных оптимизаций.

class Heavy {
    mutable bool cached{false};
    mutable double memo{0};
public:
    double value() const {
        if (!cached) {
            memo = /* тяжёлый расчёт */ 42.0;
            cached = true;
        }
        return memo;
    }
};

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

void f(const int* p) {
    // ПЛОХО: если p указывает на действительно const-объект
    int* q = const_cast<int*>(p);
    // *q = 123; // может привести к UB
}

constexpr vs const

  • const — неизменяемость во время выполнения.
  • constexpr — значение вычисляется на этапе компиляции (если возможно). Любой constexpr по определению также const.
const double Pi = 3.1415926535;     // константа во время выполнения
constexpr int N = 2 * 3 * 5;        // вычислено на этапе компиляции

Мини-пример: конфиг только для чтения

Соберём простой класс, где const correctness делает интерфейс очевидным.

class Config {
    std::map<std::string, std::string> kv;
public:
    explicit Config(std::map<std::string, std::string> init)
        : kv(std::move(init)) {}

    // Чтение без изменений
    const std::string& get(const std::string& key) const {
        static const std::string empty;
        if (auto it = kv.find(key); it != kv.end()) return it->second;
        return empty;
    }

    // Изменение доступно только через неконстантный метод
    void set(std::string key, std::string value) {
        kv[std::move(key)] = std::move(value);
    }
};

void demoConfig() {
    Config cfg({{"mode","dev"},{"port","8080"}});
    const Config& r = cfg;

    // r.set("mode","prod"); // ОШИБКА: у const-ссылки нет set
    auto mode = r.get("mode");  // Только чтение — так и задумывалось

    cfg.set("mode","prod");    // Изменять может только неконстантный объект
}

Частые ошибки и лучшие практики

  • Не добавляйте const к возвращаемому по значению типу без необходимости: это не усиливает защиту и мешает перемещению/присваиванию у временных.
  • Предпочитайте const T& в параметрах для тяжёлых объектов; для мелких — значение.
  • Помечайте методы как const, если они логически не меняют состояние — это документирует намерение и раскрывает больше оптимизаций.
  • Используйте cbegin/cend и const-итераторы для обхода «только чтение».
  • Не злоупотребляйте mutable и const_cast — они для редких случаев (кэш, внутриклассная синхронизация).
  • Проектируйте API «по умолчанию неизменяемыми»: чем меньше точек изменения, тем проще тестировать и сопровождать.

Что дальше изучить

Константность тесно связана с правилами владения и временем жизни. Освоив const correctness, вы легче разберётесь с RAII, правилами трёх/пяти/нуля и безопасными абстракциями. Хотите структурированную практику, домашние задания и обратную связь? Попробуйте интенсив: Записаться на бесплатный модуль «Программирование на C++ с Нуля до Гуру» — отличный старт, чтобы уверенно применять const в реальном коде.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (https://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: https://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: https://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.