2011-01-14 2 views
8

После прочтения this, я понимаю, что объявление метода как const предотвращает его случайную модификацию переменных-членов класса.Constant Member Functions

  • Are const Обычно используемые методы?
  • Должны ли они использоваться для всего, которые не должны изменять переменные-члены?

ответ

14

Да, const всегда следует использовать, когда это необходимо.

Это позволяет вашему компилятору проверить вашу логику приложения, статически заявляя const-correctness бесплатно!

Некоторые люди даже говорят, что const должен быть по умолчанию, и вы должны быть вынуждены использовать mutable для непостоянного.

+1

Кроме того, вы можете перегружать функции только для определения функции 'const'. Это позволяет, например, оператору индекса, который автоматически возвращает элемент в режиме read-only *, если объект объявлен как 'const'. [* только для чтения все еще применяется только во время компиляции. 'const' не может ничего делать во время выполнения] – Mephane

+0

+1 для const-correctness. никто не упомянул об этом –

+0

Я думаю о вашем утверждении «const как значение по умолчанию, и изменен для непостоянного». Похоже на крайнее положение, но я постараюсь почувствовать, что я думаю об этом. –

6

Я использую const, чтобы сообщить о намерениях разработчиков. Если бы я намеревался, что метод является чистым запросом, а не функцией модификации, я бы оба обеспечил это и передал его с помощью «const» в подписи.

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

1

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

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

1

Объявив метод, который не должен изменять переменные-члены:

  1. Уверяет, что вы думаете, что происходит, то, что вы случайно не изменяя переменную где-нибудь.
  2. Объявляет вызывающим функциям, что этот метод не изменяет переменные-члены, устраняя необходимость читать код или полагаться на документацию, которая так говорит.

Так что да, используйте const везде, где это имеет смысл. Они не так широко используются, как хотелось бы, но, скорее всего, потому, что большинство разработчиков не видят огромной выгоды.

1

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

+0

Да, я знаю боль, когда люди забывают объявлять геттеры как const. Мы должны работать с каркасом здесь, который полностью игнорирует концепцию и имеет каждую функцию-член, включая геттеры, как неконстантную. Теперь нам нужно передать указатель/ссылки как неконтактные, мы хотим получить доступ к такому объекту, даже если мы определенно хотим когда-либо читать ... -_- – Mephane

1

Если у вас есть ссылка на const или указатель (т. Е. Указатель на const) объекта класса, вы можете ТОЛЬКО вызывать методы-члены-члены класса.

Так что, если кто-то «забыл» сделать «get» метод const, вы бы не смогли вызвать его с помощью ссылки const (существует обходное решение с const_cast, но мы не хотим его использовать!).

Так что да, если класс не будет изменен методом, то он должен быть const.

Примечание: есть некоторые случаи, когда вы хотите изменить переменную как «деталь реализации», например, ленивую загрузку или блокировку мьютекса. В таком случае вы все равно можете сделать метод const, но сделать эту переменную-член «изменчивой».

Если вы пишете виртуальный метод, он должен быть const, если никакой производный класс не нуждается в его изменении.

1

Вы должны использовать ключевое слово const, когда это возможно.

Это предотвращает вас от ошибок в коде.

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

4

Просто мое свидетельство.

Несколько лет назад, я все еще был против использования сопзЬ, только из-за ограничений в области дизайна и написания длинных подписей функции ... и так далее ...

Но один из моих руководителей проектов всегда настаивал , все время, напоминая мне: «Вы должны использовать функцию const, это позволяет избежать несчастных случаев и делать не-смысл».

И в один прекрасный день я столкнулся с ошибкой . Дни после дней после дня ... Кошмар. Дизайн был слишком большим для меня, так что я мог понять его в целом. Я искал напрасно, пока не решил, что потерялся.

Затем я потратил два дня на переопределение ВСЕ функции, которые должны быть const. Я имею в виду это, два дня. (Повторная компиляция была длинной, так как она составляла 5 миллионов строк кода проекта).

А потом: просто я нашел ошибку ... скорее, компилятор нашел ошибку для меня: в методе, подобном getter, который должен был дать мне предпочтительный размер элемента управления gui, код фактически вычислял размер, но он также кэшировал свой размер и обновлял его размер ... Таким образом, изменяя объект.

Теперь, иногда я забываю поставить const. Но если я это заметлю, я исправлю это.

+0

Болезненная история. :) – GManNickG