Скажем, у меня есть следующая функция-член:
void CFoo::regWrite( int addr, int data )
{
reg_write( addr, data ); // driver call to e.g. write a firmware register
}
Ясно, что вызов этой функции не изменяет внутреннее состояние объекта, для которого она вызывается. Тем не менее, это меняет состояние любого этого Foo
пример представляет собой.
При таких обстоятельствах следует Foo::regWrite(int addr, int data)
быть константной функцией?
Вы должны решить, что означает «логически постоянный» для класса CFoo
и это зависит от того, для чего предназначен класс.
Если CFoo
истолковывается как ссылаясь на некоторые данные, тогда может иметь смысл изменить эти данные с помощью const
экземпляр CFoo
, в этом случае ваша функция-член будет const
, Для примеров этого рассмотрим другие типы, которые ссылаются на некоторые данные — вы можете изменить ссылку и char *const
или const std::unique_ptr<char>
,
Если CFoo
истолковывается как владеть некоторыми данными, тогда может иметь смысл запретить модификацию через const
экземпляр CFoo
, В качестве примеров этого рассмотрим контейнеры, в которых элементы логически являются «частью состояния объекта», даже если они физически не являются частью объекта. Так vector::operator[]
имеет постоянную перегрузку, которая возвращает const T&
а не T&
, insert
функция-член неконстантна и т. д.
Программист должен определить, что «const» должно означать для класса. Со спецификатором mutable
Вы даже можете иметь const
объект с изменяющимися значениями в элементе. Когда дело доходит до аппаратного обеспечения, можно рассматривать конфигурацию как цель для правильности констант: пока конфигурация не изменяется, объект можно считать постоянным.
Аналогичная проблема возникает, если у вас есть указатели на другие объекты в вашем классе: ваш метод const может затем вызывать неконстантные методы для другого объекта и, таким образом, модифицировать его.
Если вы посмотрите на аппаратное обеспечение как на какой-то другой объект, на который ссылается ваш класс, было бы совершенно правильно изменить настройки прошивки (поскольку изменяется только объект, на который ссылается). Если вы хотите, чтобы ваш класс «представлял» аппаратное обеспечение (или его часть), я бы предпочел не отмечать метод как const
,
Поэтому я думаю, что это в основном зависит от того, как вы разработали свой класс.
Есть два способа взглянуть на это — угол оптимизации и логика этого объявления. Что важнее, решать вам.
РЕДАКТИРОВАТЬЯ сделал несколько неверных предположений. Похоже, что компилятор на самом деле не свободен для выполнения приведенных ниже оптимизаций, а сделает их только путем анализа тело метода, чтобы гарантировать, что никакие модификации не происходят (и даже тогда только в простых случаях).
Имея это
const
позволит компилятору немного оптимизировать
Больше. Это знает чтоregWrite
не меняет поля в
объект, так что он может хранить их, если он хранит их в регистрах, и
делать аналогичные оптимизации, которые опираются на объекты поля Не существует
изменилось.Это действительно единственное, от чего будет зависеть компилятор
сделать такое определение, так что имея этоconst
в порядке и может
Теоретически разрешить лучшую производительность.
Это не интуитивно, чтобы иметь const
метод, целью которого является деструктивное изменение. Обычная интуиция программиста заключается в том, что пока я вызываю только методы const, результаты других const
методы не должны меняться. Если вы нарушаете этот неписаный контракт, ожидайте, что люди будут удивлены — даже если с компилятором все в порядке.
Я не уверен, будет ли это здесь нарушено — это будет зависеть от другого кода в этом классе. Однако, если не важны другие соображения (производительность и т. Д.), const
является (для меня) главным образом маркером на интерфейсе, который говорит, что «вызов этого не меняет состояние этого объекта», для широкого определения «состояния».
Однако это мрачное основание, и от вас зависит, что вы считаете изменением состояния. Если вы думаете, что ваш объект прошивки представляет ссылка на сайт для внутренних органов, написание реестра ничего не меняет в этом ссылка на сайт и является постоянным Если вы думаете, что это представляет состояние базовых регистров, то запись в регистры — это изменение состояния.