Іноді я думаю, що це корисно. Можливо, мені доведеться передати таблицю і хочу переконатися, що вміст таблиці не змінюється.
Однак у більшості зразків програми Objective-C я ніколи не бачу const
. Моє питання чому?
Іноді я думаю, що це корисно. Можливо, мені доведеться передати таблицю і хочу переконатися, що вміст таблиці не змінюється.
Однак у більшості зразків програми Objective-C я ніколи не бачу const
. Моє питання чому?
Відповіді:
Завдяки тому, як працюють об'єкти Objective-C, він const
перестає бути виконавцем і починає бути позначенням для програміста. Розглянемо цю програму:
int f(const int x) {
return ++x;
}
int main(int argc, char *argv[]) {
@autoreleasepool {
int x = 3;
NSLog(@"%d", f(x));
}
return 0;
}
Це насправді не компілюється тут (я використовую clang): компілятор може виявити спробу змінити примітивний тип C і видає помилку. Але тепер порівняйте це з цією програмою:
NSMutableString *f2(const NSMutableString * const x) {
[x appendString: @" world!"];
return x;
}
int main(int argc, char *argv[]) {
@autoreleasepool {
NSMutableString *x = [@"Hello" mutableCopy];
NSLog(@"%@", f2(x));
}
return 0;
}
Незважаючи на те, що функція передається постійним вказівником на постійний об'єкт, все одно можливо мутувати об'єкт.
У об'єктно-орієнтованому програмуванні найкращий спосіб закріпити постійний характер об'єкта - це зробити цей об'єкт непорушним - тобто не надати жодних методів, які можуть змінити його стан. Уявіть, що вищевказана функція взяла NSString
аргумент замість цього NSMutableString
, і що я передав буквальне, @"Hello"
а не змінне копію. Зараз, розумно кажучи, немає шансів вимкнути переданий об'єкт [*]. Objective-C не має жодного способу забезпечення цього, хоча, на відміну від const
або final
посилань на об'єкти в інших мовах ОО.
Для порівняння, const
у C ++ працює зовсім по-іншому. Якщо я отримую const
посилання на об'єкт C ++, мені дозволяється лише викликати const
функції члена на цьому об'єкті. Ці функції зберігають const
-ness об'єкта, або не вносячи будь-яких змін, або лише змінюючи змінні члена, які явно були позначені mutable
дизайнером класів. Тож уявіть, що у мене був якийсь тип MutableString
C ++, що еквівалентно NSMutableString
в Objective-C. Еквівалент мого прикладу вище виглядатиме приблизно так:
MutableString& f3(const MutableString& x) {
x.appendString(" world!");
return x;
}
Це однозначно не буде компілюватися: крім того, що appendString()
не є const
операцією, функція видаляє const
класифікатор з посилання на тип, для якого потрібна а const_cast
.
[*] Я сподіваюся, що існує якийсь перекручений спосіб зробити це, але зараз ми перебуваємо у царинах одного програміста, який намагається саботажувати іншого, роблячи "розумні" речі.
const
декор як значущий, тому ви отримуєте викривлення, як псевдоніми або касти, щоб придушити попередження, але поведінку програми в цьому зміні не змінюється.
const
все ще може бути корисним у «Цілі C», щоб стверджувати, що вказівник на об’єкт ніколи не призначається для вказівки на інший об’єкт . Тобто з NSString * const x
вами знаєте, що x
завжди буде одна і та ж струна, а не інша.
Що стосується Цілі C - я не програмую її, тому не можу відповісти на питання. Хоча питання, на яке я можу відповісти: "Чи повинні люди const
багато використовувати при програмуванні в" Цілі С "?" - це однозначне "Так".
Constness - це, по суті, функція захисту програмного забезпечення, яка використовується для того, щоб зробити програми більш надійними та доступними. Багато програмістів виростають, не дуже оцінюючи значення const
s, поки одного дня не трапиться щось погане, і у них з’явився момент "А-а-ха" - "О, це для чого const
використовується". Цілком можливо написати програму без констант, зробити таку програму надійною практично неможливо.
Багато зразків коду насправді не є програмами, а лише фрагментами, розробленими для показу конкретної функції. Вони не використовуються, const
оскільки це відволікає від точки, яку намагається зробити зразок. Другий тип коду, який ви бачите, - це код, написаний недосвідченими програмістами, які ґрунтуються на тому, що вони роблять на прикладах, з яких вони дізналися, або тих, які знають про константи, і занадто ліниві використовувати їх.
Я не використовував aim-c дуже давно.
Однак мені цікаво, чому жоден орган не згадує цей аспект.
У Objective-c вже є щось інше, пов’язане з постійним. Змінюваність
Наприклад, Nstring * буде вказувати на постійний рядок. Якщо ви хочете, щоб рядок ви могли змінити, ви використовуєте NMutableString або щось подібне. Цей NMutableString надасть додаткові методи, що дозволяють людям змінювати рядок.
А що робити, якщо ви хочете, щоб сам вказівник був постійним. Мені ніколи про це не потрібно хвилюватися, кодуючи дуже великий проект.
Тож я думаю, що саме тому.