Как ты стал обращенным в констант? [закрыто]


25

После 15 лет C ++ я до сих пор не научился любить, используя const. Я понимаю, что это полезно, но на самом деле я никогда не был в ситуации, когда правильное поведение могло бы избежать проблемы, с которой я столкнулся.

Так как же ты полюбил льготы супругов?


3
Я думаю, что правильность const - это скорее правильность, чем инструмент для решения такой проблемы, как оператор if constrcut или sizeof.
legends2k

9
«Причина, по которой const работает в C ++, заключается в том, что вы можете отбросить его. Если вы не можете его выбросить, тогда ваш мир будет ужасным». - Андерс Хейлсберг
Мейсон Уилер

1
const также является модификатором типа C. Он существует с первого стандарта ANSI C.
Гуперникетес

Будучи избалованным Java / C #, я параноик, который любит оставлять, утверждает, что у меня есть все шансы. Что может пойти не так, то пойдет не так. Если есть помощь во время компиляции или во время выполнения, подсчитайте меня! Я стал новообращенным, как только услышал об этом 3-4 раза, и перешел по этой ссылке (достаточно, чтобы увидеть синтаксис, мне не нужно было читать о причинах этого): creation.com/Cpp/const.html Просто потому, что что-то еще не взорвалось мне в лицо ... нужно немного усилий, чтобы быть правильным, и это не повредит. Проверьте мысли Джоэла: joelonsoftware.com/articles/Wrong.html
Работа

Ответы:


28

Ну, я не был убежден, пока не попытался принять философию.

Я сначала начал с того, что поставил constдействительно доступным только для чтения членам моих самых простых членов класса и аргументы функций-членов.

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

Это заразно. Большая часть кода получила еще больше константности, и мне было легче отлаживать ее, потому что это дает вам уверенность в том, что компилятор остановит вас, если вы начнете модифицировать что-то, чего не должны делать.

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

Я был убежден.

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


8
+1 для заразных, что по сути означает, что вы либо должны стать константой, либо полностью избегать ее.
Мартин Уикман,

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

4
+1 для «было легче отлаживать», я использую constдаже для локальной переменной, которую, я знаю, мне не нужно менять, таким образом, при чтении кода я могу просматривать a ifили a forили whatelse: моя переменная является константой, я знаю, это не изменится! Мне было наплевать на оптимизацию, но у меня ограниченный мозг, и очень мало помогали отступы + корректность констант!
Матье М.

@MatthieuM .: Когда-нибудь задумывались о переходе на Haskell? ;-)
Джорджио

@ Джорджио: Я изучил это, даже пошел до покупки "Real World Haskell". Честно говоря, по умолчанию я не в восторге от лени и множества загадочных операторов.
Матье М.

15

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

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

(Между прочим, я поиграл с идеей создания форка GCC для диалекта C ++, в котором все типы, constкроме как явно определены как mutable. Если есть поддержка такой вещи, я полностью обязуюсь поддерживать и использовать ее.)


С точки зрения ОО, неизменяемость обеспечивает инкапсуляцию, предотвращая неограниченный доступ для записи. Это уменьшает связь между классами, потому что неизменяемые объекты должны полностью управлять своим собственным состоянием и, следовательно, вести себя как обычные значения. Корректность const значительно облегчает процесс подтверждения правильности программы, особенно в контексте параллельного программирования. С помощью ссылки на C ++ и семантики ссылок на значения C ++ 0x вы можете использовать неизменяемые объекты, не беспокоясь о копировании их повсюду. Кроме того, компилятор может применить довольно удивительную магию оптимизации, если вы работаете с в основном неизменяемыми объектами.

Я знаю, что печатать constвезде - отстой , но вы быстро привыкаете к нему, и со временем преимущества становятся очевидными с точки зрения надежности и удобства обслуживания. Я не гениальный писатель, и, кажется, это доказанная трудная задача, чтобы обосновать это, но я знаю, что правильность const была чрезвычайно полезна для меня как разработчика при разработке и реализации программ, и я думаю, что опыт лучший учитель в этом отношении.


2
Вы просто сказали, что правильность констант - это хорошо. Вы сказали, что это «ведет к более безопасному, лучшему коду». Можешь сказать почему?
Дэвид Рейс

Я нахожусь в лагере неизменности, мой любимый язык - Erlang. Но я бы сказал, что неизменность с помощью const в C ++ на самом деле не бесплатна. Есть недостатки, такие как менее читаемый код, константные и неконстантные версии одного и того же метода или отбрасывание констант, потому что «другого выбора просто не было».
Грок

1
Я бы посоветовал не просто использовать mutable, поскольку он имеет четкое значение с точки зрения правильности const. Это означает, что этот объект данных может изменяться способами, которые не влияют на поведение объекта, и допускает такие вещи, как кэширование ответов. Составьте другое ключевое слово.
Дэвид Торнли

2
@ Дэвид Торнли: Ради последовательности, mutableэто логичный выбор. void alter(mutable Point&)имеет смысл, как и mutable int fooдля локальной переменной, и ни один из этих конфликтов не конфликтует с существующим языком или существующим использованием mutable. Кроме того, Object mutable* mutableвыглядит достаточно страшно, чтобы быть предупреждением о необходимости или правильности.
Джон Перди

Если вы когда-нибудь сделаете ответвление, подумайте о том, чтобы пойти с CLang вместо этого - должно быть менее болезненным.
Gf

6

Преимущество правильности const состоит в том, что она налагает дисциплину на программу и облегчает рассуждение об отдельных частях программы.

Дисциплина в том, что вам нужно знать, где что-то может измениться. Соответствующее преимущество состоит в том, что легче увидеть, что делает фрагмент кода, когда вы можете сказать, что может изменить состояние.


1
«Программы должны быть написаны для того, чтобы люди могли читать, и только для машин». - Абельсон и Суссман, SICP
Брэндон Дюретт

4

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

PS: я полностью убедился в том, constчто понял правильность его использования;)



2

Я вижу две основные причины написания правильного кода. Во-первых, компилятор - ваш друг, и с помощью const вы позволяете ему предупреждать о потенциальных ошибках. Вторая причина в том, что правильность const делает код более читабельным. Например, вы всегда знаете, какие аргументы функции являются входными, а какие выходными. Вы также знаете, какие функции-члены изменяют объект, а какие нет. Вы знаете эти вещи мгновенно, не читая код. Это, конечно, предполагает очень разумное использование const_cast.


2

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

  • Читаемость и понимание. Если я читаю чужой код и функция принимает константную ссылку в качестве параметра, я знаю, что этот параметр предназначен только для использования в качестве переменной только для чтения. Это огромный выигрыш, особенно если код многопоточный.
  • Компилятор может использовать квалификатор const, чтобы помочь его проходам оптимизации.
  • Скажем, у меня есть объект класса А в ситуации, когда я не хочу, чтобы он изменился. Тогда единственными функциями-членами, которые могут быть вызваны для этого объекта, являются те, которые являются константными.

2

Суммируйте два момента, которые были рассмотрены в других ответах, и добавьте новый:

  • constдокументирует код пользователям вашего API. Он формирует договор между функцией и вызывающей стороной, что функция не будет изменять свои параметры. (Обратите внимание, что const_castфункция не позволяет функции изменять свой параметр, она позволяет передавать этот параметр другим функциям, которые не изменяют свои параметры, но забыли constаннотацию.) Это также полезно в функциях / loop / etc, потому что это помогает понять многое так же, как инвариант цикла.

  • constдокументирует ваше намерение компилятору. Поиск ошибок во время компиляции всегда лучше, чем ожидание выполнения этого фрагмента кода.

  • constнеобходим для безопасного типа полиморфизма. Указатели (во всех их формах, а не только необработанные указатели) являются ковариантными, только если они есть const(Примечание: не то же самое, что «указатель на const»). Covariance требуется интерфейс только для чтения, а для контравариантности - интерфейс только для записи.

Второе из них я узнал первым. Я начинал constтолько с цели указателя и опорных параметров, пока не начал видеть преимущества отлова ошибок раньше, и начала использовать его на локальных компьютерах и т. Д.

Затем я узнал, что большинство #defines можно заменить (в C ++) глобальными константами с дополнительными преимуществами безопасности типов. Так что я тоже там использовал.

Наконец, я взял класс по системам типов и лямбда-исчислению и узнал, что constи нетипы constпринципиально различны (так как они поддерживают разные операции), и с тех пор я никогда даже не думал о написании кода C ++ без интенсивного использования const.


1

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

Это тот же принцип, но я просто хотел добавить практическую причину использования const.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.