Что именно означает ключевое слово const
в С++, когда оно написано в конце функции-члена (после списка аргументов)?
В чем смысл константы в конце функции-члена?
Ответ 1
Это означает, что *this
const
внутри этой функции-члена, т.е. не изменяет объект.
Ключевое слово
this
- это выражение prvalue, значение которого является адресом объекта, для которого вызывается функция. Типthis
в членной функции классаX
равенX*
. Если функция-член объявлена const
, типthis
равенconst X*
. [раздел 9.3.2 §1]В функции члена
const
объект, для которого вызвана функция, обращается через путь доступаconst
; поэтому функция-членconst
не должна изменять объект и его нестатические элементы данных. [раздел 9.3.2 §2]
Это означает, что функция-член const
может быть вызвана в экземпляре const
класса. Элемент-член не const
не может быть вызван в объект [1] a const
, так как он потенциально может попытаться его изменить.
[1] Примечание: временный объект не является const
, если он не имеет тип const
.
Ответ 2
const
в конце сигнатуры функции означает, что функция должна принять объект, членом которого он является const
. На практике это означает, что вы попросите компилятор проверить, что функция-член не изменяет данные объекта каким-либо образом. Это означает, что компилятор должен проверить, что он напрямую не изменяет данные элемента, и не вызывает никакой функции, которая сама не гарантирует, что он не изменит объект.
Когда вы создаете объект const
, вы просите компилятор убедиться, что этот объект не изменился за пределы его инициализации. Это по очереди означает, что компилятор проверяет, что вы напрямую не изменяете его данные-члены, и что вы не вызываете какую-либо функцию, которая не гарантирует, что она не изменит объект.
Это все часть философии const correct. По сути, это означает, что если все будет работать прямо сейчас, и они не изменятся, они никогда не сломаются. Другими словами, постоянные вещи легче работать с надежностью. Эта const
вещь в конце сигнатур функций - это инструмент, позволяющий вам запрещать вещание. Это по очереди означает, что вы должны положить const
везде, где это возможно.
Ответ 3
Оптимизация компилятора возможна, но главным преимуществом является выполнение контракта, выраженного в объявлении функции - если вы определяете функцию-член как const
, компилятор предотвращает любую модификацию объекта внутри этой функции.
Вы можете освободить отдельные поля в классе от этого ограничения, используя mutable
в своем объявлении. Это полезно, например, когда у вас есть класс, который инкапсулирует свой собственный lock_guard, который должен изменить его значение, чтобы обеспечить безопасность потока даже внутри функций-членов const
.