Як ви стали конвертувати правильність const? [зачинено]


25

Після 15 років C ++ я все ще не навчився любити, використовуючи const. Я розумію, що це корисно, але я ніколи насправді не бував у ситуації, коли коректність, що дозволило б уникнути проблеми, з якою я стикався.

Отже, як ви полюбили переваги consts?


3
Я думаю, що коректність const є скоріше правильною, ніж інструментом для вирішення проблеми, як, наприклад, constrcut або оператор sizeof.
legends2k

9
"Причина того, що const працює в C ++, полягає в тому, що ви можете відкинути його. Якби ви не змогли його відкинути, то ваш світ би висмоктався". - Андерс Хейлсберг
Мейсон Уілер

1
const також є модифікатором типу C і був з першого стандарту ANSI C.
Huperniketes

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

Відповіді:


28

Ну, я не переконався, поки не спробував прийняти філософію.

Я спершу розпочав з викладу constдійсно лише членів моїх основних класів та аргументів функцій членів.

Звідти я вже не міг складати. Потім я наполегливо збирався в коді за допомогою цих базових класів, побачив, чи були раніше constдоповнення справді легітимними порівняно з використанням, який я їх зробив. Це допомогло мені виправити деякі помилки на шляху, оскільки я додав constness в інші частини коду.

Це заразно. Більшість коду отримала ще більшу чистоту, і мені було легше налагодити його, тому що ви впевнені, що компілятор зупинить вас, якщо ви почнете змінювати щось, чого не слід.

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

Я був переконаний.

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


8
+1 для заразного, що по суті означає, що ви або повинні стати конвертом конституції, або повністю його уникати.
Мартін Вікман

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

4
+1 для "мені було простіше налагоджувати", я використовую constнавіть для локальної змінної, яку я знаю, що мені не потрібно буде змінюватись. Таким чином, під час читання коду я можу перебирати через ifабо forабо whatelse: моя змінна постійна, я знайте, це не зміниться! Я не міг би менше піклуватися про оптимізацію, але у мене обмежений мозок, і мало рівня відступів + коректність правильності дуже допомагають!
Матьє М.

@MatthieuM. Ви коли-небудь думали про перехід на Haskell? ;-)
Джорджіо

@Giorgio: Я досліджував це, навіть зайшов так далеко, як купувати "Реальний світ Haskell". Якщо чесно, я за замовчуванням не в захваті від ліні та багатьох криптовалют, що виникли.
Матьє М.

15

Я ніколи не був прихильником об’єктно-орієнтованого програмування, і якщо що-небудь менше, то я більше дізнаюся про програмування взагалі. Як я вивчав різні парадигми програмування, я зрозумів , що незмінність є однією з самих центральних концепцій розробки програм, які зачіпають програмне забезпечення , написане в відповідно до якої - небудь філософії. Це надзвичайно важливо у функціональному програмуванні, що впливає на оптимізацію та одночасність, окрім простих гарантій безпеки.

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

(До речі, я зіграв з ідеєю створити вилку GCC для діалекту C ++, в якому всі типи, constякщо явно не кваліфіковані як mutable. Якщо є підтримка такої речі, я повністю зобов’язуюсь її підтримувати та використовувати.)


З точки зору ОО, незмінність застосовує інкапсуляцію, запобігаючи необмеженому доступу до запису. Це зменшує зв’язок між класами, оскільки незмінні об'єкти повинні повністю керувати власним станом і, таким чином, поводитись як звичайні значення. Правильність Const значно полегшує процес доведення правильності програми, особливо в контексті одночасного програмування. За допомогою посилань C ++ та еталонної семантики C ++ 0x rvalue ви можете використовувати незмінні об'єкти, не турбуючись про накладні копіювання їх у всьому місці. Крім того, компілятор може працювати надзвичайно дивовижною магією оптимізації, якщо ви працюєте з переважно незмінними об'єктами.

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


2
Ви в основному просто сказали, що коректність const є доброю справою. Ви сказали, що це "призводить до безпечнішого, кращого коду". Ви можете сказати, чому?
Девід Рейс

Я повністю перебуваю в таборі непорушності, моя улюблена мова - Ерланг. Але я заперечую, що незмінність через const в C ++ насправді не є безкоштовною. Є такі недоліки, як менш читабельний код, версія const і non const того ж методу або відкидання const away, оскільки іншого вибору просто не було ».
grok

1
Я б радив не просто використовувати mutable, оскільки це має чітке значення з точки зору коректності const. Це означає, що цей об'єкт даних може змінюватися способами, які не впливають на поведінку об'єкта, і дозволяє такі речі, як кешування відповідей. Складіть ще одне ключове слово.
Девід Торнлі

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

Якщо ви коли-небудь будете робити виделку, подумайте, замість того, щоб поїхати з CLang замість цього - має бути менш болісно.
gf

6

Перевага коректності коректності полягає в тому, що вона накладає дисципліну на програму і полегшує міркування про частини програми.

Дисципліна полягає в тому, що вам потрібно знати, де щось може змінитися. Відповідна перевага полягає в тому, що простіше зрозуміти, що робить фрагмент коду, коли ти можеш сказати, що може змінити стан.


1
"Програми повинні бути написані для того, щоб люди могли читати, і лише випадково, щоб їх виконали машини." - Абелсон і Суссман, SICP
Брендон Дюретт

4

Будучи const коректним підкреслює правильність дизайну, який я розглядаю близько до аналогічного питання, який не використовує операторів лиття; тому не використовуйте кастинг і не будете правильним, мінімальне використання змінних - все це покажчики для вимірювання того, наскільки хороша конструкція, але не власне інструменти для вирішення загальної проблеми.

PS: Я повністю переконався, constщойно зрозумів правильність його використання;)



2

Я бачу дві основні причини написання const-правильного коду. Одне полягає в тому, що компілятор є вашим другом, і використовуючи const, ви дозволяєте попередити вас про можливі помилки. Друга причина полягає в тому, що const-коректність робить код більш читабельним. Наприклад, ви завжди знаєте, які аргументи функції - це вхідні дані, а які - вихідні. Ви також знаєте, які функції учасників модифікують об'єкт, а які ні. Ви знаєте ці речі миттєво, не читаючи код. Звичайно, це передбачає дуже розумне використання const_cast.


2

Я став наверненням, як тільки зрозумів, що це можливо. Це мало сенс для мене з точки зору "хорошого стилю програмування". Існують різні причини, чому найкраще бути правильним:

  • Зрозумілість та розуміння. Якщо я читаю чужий код, а функція бере параметр const як параметр, я знаю, що параметр призначений лише для використання в якості змінної, доступної лише для читання. Це величезна виграш, особливо якщо код є багатопоточним середовищем.
  • Компілятор може використовувати класифікатор const, щоб сприяти його оптимізації.
  • Скажіть, у мене є об’єкт класу А в ситуації, коли я не хочу, щоб він мінявся. Тоді єдиними функціями-членами, які можна викликати для цього об'єкта, є ті, що є const.

2

Узагальнити два моменти, які охоплені в інших відповідях, і додати новий:

  • constдокументує код користувачам вашого API. Він формує контракт між функцією та її абонентом, що функція не змінює її параметри. (Зверніть увагу, що const_castфункція не дозволяє змінювати свій параметр, вона дозволяє передавати цей параметр іншим функціям, які не змінюють своїх параметрів, але забули constанотацію.) Він також корисний у функціях / циклі / тощо, оскільки він допомагає зрозуміти багато так само, як цикл інваріант.

  • constдокументує ваш намір компілятору. Знайти помилки під час компіляції - це завжди краще, ніж чекати запуску цього фрагмента коду.

  • constнеобхідний для безпечного поліморфізму типу. Покажчики (у всіх їхніх формах, а не лише необроблені покажчики) є коваріантними лише тоді, коли вони є const(Примітка: не те саме, що "покажчик на const"). Коваріація вимагає інтерфейсу лише для читання, а для протиріччя - інтерфейс, призначений лише для запису

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

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

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


1

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

Це той самий принцип, але я просто хотів додати практичну причину використання const.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.