const ключевое слово С++

Ключевое слово const служит для создания неизменяемой (константной) переменной, указателя или функции и т.д.

Константные переменные и указатели


#include <iostream>
int main() {
    int const a = 1;           // Теперь переменную нельзя изменить, она всегда равна 1. Нельзя a = 3;
    const int b = 2;           // То же самое. const может быть до и после типа. Нельзя b = 5;
    int c = 5;                 // Обычная переменная
    const int* pa = &a;        // Можно   pa = &b но нельзя *pa = b
    int* const pc = &c;        // Можно  *pb = b но нельзя   pb = &b
    const int* const p = &a;   // Нельзя *p = b и нельзя     p = &b
    std::cout << "a = " << a << "\nb = " << b << "\nc = " << c << "\npa = " << pa << ", *pa = " << *pa << "\npc = " << pc << ", *pc = " << *pc << std::endl;
}
/* Вывод программы
a = 1
b = 2
c = 5
pa = 0x61fe6c, *pa = 1
pc = 0x61fe68, *pc = 5
*/

Существует мнемоническое правило, позволяющее легко запомнить, к чему относится const. Надо провести черту через "*", если const слева, то оно относится к значению данных; если справа — к значению указателя.
Мнемоническое правило для запоминания константных указателей С++

Константные функции и объекты

Константные функции не могут изменять объект для которого вызываются.

Константные объекты могут вызывать только константные функции.


#include <iostream>
class A {
    int x = 10;
public:
    A(int val){ // Конструктор
        x = val;    // Можно менять x не из константных функций
    }
    void print_con(int a) const { // Константная функция
        std::cout << "a = " << a << ", x = " << x << std::endl;
        a = x; // OK
//      x = a; // Ошибка. изменение объекта константной функцией
    }
    void print(){
        std::cout << "x = " << x << std::endl;
    }

};

int main() {
    A a(20);         // Создаем объект
    a.print();       /// x = 20
    const A b(30);   // Создаем константный объект
//  b.print();       // Ошибка. Нельзя вызывать неконстантную функцию из константного объекта
    b.print_con(40); /// a = 40, x = 30
}

Константные аргументы функции

1) Аргументы передаваемые по ссылке или указатели рекомендуется указывать как константные, если их не изменяют внутри функции, это хорошо описывает назначение кода и не дает случайно изменить аргумент (будет ошибка компиляции).

2) Для указателя в аргументах функции можно указывать const до звездочки (константное значение указателя) и после звездочки (константный адрес указателя), тогда будет ошибка компиляции при попытке изменить значение или адрес указателя. Если указать только первый const (до звездочки) - то изменить адрес указателя можно будет внутри функции, но снаружи (переданный в функцию указатель) не изменит значения или адрес.


#include <iostream> // std::cout
using namespace std;

void func(int& arg){    // Функция принимает по ссылке аргумент
    arg = 10;           // Присваивание аргумента значения 10
}

void func_const_link(const int& arg){ // Функция принимает по ссылке аргумент определенный как константа
    //arg = 10;       // Ошибка! Нельзя менять константный аргумент
}

void func_const_ptr(const int* arg){ // Функция принимает константный указатель
    //*arg = 10;        // Ошибка! Нельзя менять значение константного указателя
    arg = nullptr;      // Изменять адрес можно, но это не имеет эффекта, внешний указатель не меняется...
}

void func_const_const_ptr(const int* const arg){ // Функция принимает константный указатель
    //*arg = 10;        // Ошибка! Нельзя менять значение константного указателя (первый const)
    //arg = nullptr;    // Ошибка! Нельзя менять адрес константного указателя (второй const)
}

int main(){
    int a = 1;                      // Целочисленная переменная a

    cout << "a = " << a << endl;    //a = 1
    func(a);                        // Передали a по ссылке в функцию и там изменили
    cout << "a = " << a << endl;    //a = 10

    int* pa = &a;                   // Указатель на a
    cout << "*pa = " << *pa << ", pa = " << pa << endl; //*pa = 10, pa = 0xb47e7ffb64
    func_const_ptr(pa);             // Передали указатель в функцию где ему меняют адрес
    cout << "*pa = " << *pa << ", pa = " << pa << endl; //*pa = 10, pa = 0xb47e7ffb64 Значение и адрес указателя не изменились

    const int* const pca = &a;      // Константный указатель на a
    cout << "*pca = " << *pca << ", pca = " << pca << endl; //*pca = 10, pca = 0xb47e7ffb64
    //func(*pca);                   // Ошибка! Функция ожидает неконстантное значение
    func_const_ptr(pca);            // Передали указатель в функцию где ему меняют адрес
    cout << "*pca = " << *pca << ", pca = " << pca << endl; //*pca = 10, pca = 0xb47e7ffb64 Значение и адрес указателя не изменились
}
2023-10-22



Понравилась страница?
Добавить в закладки
Или поделиться!

Связанные темы

Оператор and альтернатива оператору "Логическое И" &&
Оператор and_eq - альтернатива оператору &= (Побитовое И)
asm ключевое слово С++. Включение блока кода на языке ассемблер в код С++.
auto C++, автоматическое вычисление компилятором типа переменной
bitand оператор С++ альтернативный "Побитовое И" &
bitor оператор языка С++ аналогичный "Побитовому ИЛИ" |
bool логический тип данных в С++
break оператор завершения ближайшего цикла или case в С++
case оператор С++ для выполнения блока кода при совпадении целочисленного значения в операторе switch
catch оператор С++ для ловли исключений
class ключевое слово C++ для задания класса
compl оператор C++ альтернативный "Побитовая инверсия" ~
const ключевое слово С++
consteval спецификатор С++20 указывающий что каждый вызов функции должен создавать константы времени компиляции
constexpr спецификатор С++11 означающий что значение переменной или результат работы функции должны рассчитываться на этапе компиляции
const_cast оператор приведения типов для добавления или удаления cv-квалификаторов С++
dynamic_cast С++ преобразование указателей или ссылок на объект
false C++, логическое "Ложно" C++
inline C++ вставка кода функции в месте вызова
Ключевые слова в С++
namespace С++ пространство имен
noexcept в C++
register С++ зарезервированное ключевое слово
return C++ выход из функции с возвратом результата
Выражения rvalue, lvalue, gvalue, xvalue, prvalue.
throw C++ принудительное выбрасывание исключений
true C++ логическое истинно и любое число кроме нуля
try C++ начинает блок кода в котором ловятся исключения
using C++ создание псевдонимов и импорт из пространства имен
volatile С++ запрет оптимизации объекта который может измениться извне