Це здебільшого стосується другого рядка: найкращі практики, завдання, параметри функцій тощо.
Загальна практика. Спробуйте зробити все, const
що можете. Або, якщо сказати іншим способом, зробити все const
для початку, а потім видалити саме мінімальний набірconst
s, необхідний для того, щоб програма могла функціонувати. Це буде великою підмогою у досягненні коректності const та допоможе забезпечити, щоб тонкі помилки не вводилися, коли люди намагаються привласнювати речі, які вони не повинні змінювати.
Уникайте const_cast <>, як чума. Є один або два законні випадки використання для цього, але їх дуже мало і між ними. Якщо ви намагаєтесь змінити const
об'єкт, ви зробите набагато краще, щоб знайти того, хто заявив про це const
в першому темпі, і поговоріть з ними справу, щоб досягти консенсусу щодо того, що має статися.
Що веде дуже акуратно до виконання завдань. Ви можете призначити щось, лише якщо це не const. Якщо ви хочете призначити щось, що є const, див. Вище. Пам'ятайте, що в деклараціях є int const *foo;
і int * const bar;
різні речіconst
- інші відповіді тут висвітлювали це питання із захопленням, тому я не буду в цьому займатися.
Параметри функції:
Передайте значення: наприклад, void func(int param)
вам не байдуже в той чи інший спосіб на веб-сайті, що телефонує. Можна зробити аргумент, що є випадки використання для оголошення функції як, void func(int const param)
але це не впливає на абонента, лише на саму функцію, оскільки те, яке значення передане, не може бути змінено функцією під час виклику.
Пройти за посиланням: наприклад, void func(int ¶m)
зараз це має значення. Оскільки щойно оголошені func
дозволено змінюватись param
, і будь-який сайт, що телефонує, повинен бути готовий боротися з наслідками. Зміна декларації на void func(int const ¶m)
зміну договору та гарантії, які func
тепер не можуть змінитисяparam
, тобто передається те, що вийде. Як зазначають інші, це дуже корисно для дешевого проходження великого об'єкта, який ви не хочете змінювати. Пройти еталон набагато дешевше, ніж передавати великий об'єкт за значенням.
Проходить покажчик: наприклад , void func(int *param)
і void func(int const *param)
ці два досить багато синонімів їх позиційні колегами, з одним застереженням , що викликається, тепер необхідно перевірити , nullptr
якщо деякі інші договірні гарантії запевняють , func
що він ніколи не отримає nullptr
вparam
.
Оглядова стаття на цю тему. Довести правильність у подібній справі пекельно важко, просто помилково помилитися. Тому не ризикуйте і завжди перевіряйте параметри вказівника на nullptr
. Ви вбережете себе від болю та страждань та важко знайти помилок у довгостроковій перспективі. А що стосується вартості чека, то це бруд дешевий, а у випадках, коли статичний аналіз, вбудований у компілятор, може керувати ним, оптимізатор все-таки зможе схилити його. Увімкніть генерацію часового коду посилання для MSVC або WOPR (я думаю) для GCC, і ви отримаєте програму широко, тобто навіть у викликах функцій, які перетинають межу модуля вихідного коду.
Зрештою, все вищесказане робить дуже солідним випадком, коли завжди віддають перевагу посилання на покажчики. Вони просто безпечніші навколо.