notes

Константы

Определение констант

  1. Ключевое слово const позволяет определять типизированные константы.
     double const pi = 3.14;
     const int days[4] = {31, 28, 31, 30 };
    
  2. Попытка изменить константные данные (к примеру через указатель) приводит к неопределённом уповедению
     double * pi_ptr = (double *) π
     *pi_ptr = 5;
    

    Указатели и const

  3. В С++ можно определить как константный указатель так и указатель на константу
     int a = 10;
     const int * p1 = &a; // указатель на константу
     int const * p2 = &a; // указатель на константу
     *p1 = 20; // ошибка
     p2 = 0; // ОК
    
     int * const p3 = &a; // константный указатель
     *p3 = 30; // ОК
     p3 = 0; // ошибка
    
     int const * const p4 = &a; // константный указатель на константу
     *p4 = 40; // ошибка
     p4 = 0; // ошибка
    
  4. Можно использовать следующее правило: слово const делает неизменяемым тип слева от него.
     int a = 10;
     int * p = &a;
    
     // указатель на константный указатель на int
     int * const * p2 = &p;
    
     // константный указатель на указатель на int
     int ** const p3 = &p;
    

    Ссылки и const

  5. Ссылка сама по себе является неизменяемой
     int a = 10;
     int & const b = a; // ошибка
     int const & c = a; // ссылка на константу
    
  6. Использование константных ссылок позволяет избежать копирования объектов при передаче в функцию
     Point midpoint (Segment const & s);
    
  7. По константрой ссылке можно передавать rvalue.
     Point p = midpoint ( Segment(Point(0,0), Point(1,1)) );
    

Константные методы

  1. Методы классов могут быть объявлены как const.
     struct IntArray {
         size_t size() const;
     };
    
  2. Такие методы не могут менять поля объекта (тип this - указатель на const)
  3. У константных объектов (через указатель или ссылку на константу) можно вызывать только константные методы:
     IntArray const * p = foo();
     p->resize(); // error
    
  4. Слово const является частью сигнутуры метода, метод с const и метод без - это перегрузка функции. Константный метод вызывается по ссылке или указателю на константу, в противном случае вызывается неконстантный метод.
  5. Если внутри константного метода необходимо изменить поле объекта, то это поле нужно объявить со словом mutable.
  6. Конкстантность методов в C++ обеспечивает синтаксическую константность (такие методы не могут менять поля обеъекта).
  7. Нужно понимать что константные методы не обеспечивают логическую константность (нельзя менять те данные, которые определяют состояние объекта).
     struct IntArray {
         void foo () const {
             // нарушение логической константности
             data_[10] = 1;
         }
     }