const

Материал из cppreference.com
Перейти к: навигация, поиск

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

Содержание

[править] Использование

Считается хорошей практикой использовать const где это возможно для защиты данных от непреднамеренной перезаписи. Попытка втиснуть const в программу, после того, как она была написана создает каскадный эффект. Лучше применять const как можно раньше в цикле разработки кода. Это дает нам правильное объявление и использование const.

Ключевое слово const может иметь многозначный смысл и быть использованным в множестве мест (даже бессмысленных мест).

[править] Объявления

Для понимания, что защищает const, читайте справа налево.

const char * str; // указатель на символы которые не могут быть изменены (хотя указатель может быть перенаправлен)
char const * str; // аналогично предыдущему (альтернативный способ записи)
char * const str; // нельзя изменить указатель на символы (хотя сами символы могут быть изменены)

Аналогично для ссылок в С++ (вы не можете применить const к ссылке так как ссылка не может быть перенаправлена):

const char & str; // ссылка на символ который не может быть изменен
char const & str; // тоже, что и выше

Это выглядит достаточно просто, однако более запутанные расположения могут быть более сложными для интерпретации. Рассмотрим:

char * const * data; // указатель на неизменяемый указатель на символы
char const ** data; // указатель на указатель неизменяемых символов
const char ** data; // указатель на указатель неизменяемых символов
char ** const data; // неизменяемый указатель на указатель символов 
char * const * const data; // неизменяемый указатель на неизменяемый указатель символов

Возможно, кто-то будет убеждать вас, что вы **ДОЛЖНЫ** располагать const после типа, однако вы свободны располагать его как до, так и после типа, если это регулярный тип не-указатель (например, "char"). Используйте формат, который соответствует вашему существующему коду или стандартам кодирования в вашей организации. Как во всем остальном, просто будьте последовательны. Если вы хотите применить const к указателю, вы должны расположить const после звездочки.

Также, хорошей практикой является объявлять определенные поля объекта как const, если это свойство объекта не изменяется за время жизни объекта.

[править] Параметры

Наиболее часто const используется для защиты данных на которые ссылаются или которые передаются по указателю:

void func ( const MyObject * data ); // MyObject не может быть изменен в func
void func ( const MyObject & data ); // MyObject не может быть изменен в func

Заметьте, что не важно размещается const до или после типа. Следующее эквивалентно:

void func ( MyObject const * data ); // тоже что и ( const MyObject * )
void func ( MyObject const & data ); // тоже что и ( const MyOjbect & )

Тем не менее, размещение const после указателя или ссылки меняет то, что именно является "const", так как const следующий за указателем защищает только указатель, а не данные на которые он указывает.

void func ( MyObject * const data ); // ненужная защита копии указателя на MyObject

Внутри функций, вы можете свободно манипулировать с MyObject, но не указателем на MyObject. Однако, так как значение указателя является локальным для функции (указатель был передан по значению, когда функция была вызвана), это бесполезно, так как никто вне функции не будет затронут не важно, измените вы указатель или нет.

Размещение const после ссылки совершенно бесполезно и должно быть исключено. Ссылки не могут быть перенаправлены (т.е. они уже неявно константны)

void func ( MyObject & const data ); // бесполезная защита ссылки на MyObject

Здесь const защищает ссылку, которая в любом случае не будет изменяться.

Иногда полезно возвратить приватные данные объекта. Однако, мы не хотим, чтобы приватными данными манипулировали вне класса.

const MyObject & MyClass::func ( MyObject & data ); // MyObject  возвращенный func не может быть изменен

[править] Методы

Часто методы не манипулируют какими-либо данными объекта. Эти методы, так же известные как accessors, должны быть объявлены как const. Эффект от этого в том, что указатель this внутри метода вместо того, чтобы быть "MyClass *", будет теперь "const MyClass *", тем самым они не могут изменять объект через указатель this.

void MyClass::func ( MyOjbect & data ) const; // эта функция не может манипулировать с данными класса

Заметьте, что если вы имеете константный объект, вы можете вызывать только константные методы данного объекта. (Причина в том, что когда вы вызываете метод, вы должны передать указатель на объект, как указатель this. Но, если вы имеете объект "const MyClass", тогда вы можете получить только "const MyClass *", а не "MyClass *", тем самым вы не можете вызывать константные методы.)

void MyClass::const_func() const;
void MyClass::func();
 
const MyClass object;
 
object.const_func(); // ок
object.func(); // нельзя вызвать не константную функцию для константного объекта

По тем же причинам, внутри константных методов, вы можете вызывать только другие константные методы объекта.

Related Topics: const_cast, mutable

Личные инструменты
Пространства имён
Варианты
Действия
Навигация
Инструменты
На других языках