Ze względu na sposób, w jaki działają obiekty Objective-C, const
rezygnuje z wymuszania i zaczyna być notacją dla programisty. Rozważ ten program:
int f(const int x) {
return ++x;
}
int main(int argc, char *argv[]) {
@autoreleasepool {
int x = 3;
NSLog(@"%d", f(x));
}
return 0;
}
To się właściwie nie kompiluje (używam clang): kompilator może wykryć próbę zmodyfikowania pierwotnego typu C i generuje błąd. Ale teraz porównaj to z tym programem:
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;
}
Mimo że funkcja jest przekazywana do stałego obiektu przez stały wskaźnik, nadal można mutować obiekt.
W programowaniu obiektowym najlepszym sposobem na wymuszenie stałej natury obiektu jest uczynienie go niezmiennym - tzn. Brak metod, które mogłyby zmienić jego stan. Wyobraź sobie, że powyższa funkcja wzięła NSString
argument zamiast NSMutableString
, i że przekazałem literał @"Hello"
zamiast modyfikowalnej kopii. Zasadniczo nie ma teraz szansy na mutację przekazywanego obiektu [*]. Objective-C nie ma żadnego sposobu egzekwowania tego jednak, w przeciwieństwie do const
lub final
odwołań do obiektów w innych językach oo.
Dla porównania const
działa zupełnie inaczej w C ++. Jeśli otrzymam const
odwołanie do obiektu C ++, będę mógł wywoływać const
funkcje składowe tylko na tym obiekcie. Funkcje te chronią const
-ness obiektu, albo nie dokonując żadnych zmian, albo tylko modyfikując zmienne składowe, które zostały wyraźnie oznaczone mutable
przez projektanta klasy. Więc wyobraź sobie, że miałem jakiś typ MutableString
w C ++, który jest równoważny NSMutableString
w Objective-C. Odpowiednik mojego powyższego przykładu wyglądałby mniej więcej tak:
MutableString& f3(const MutableString& x) {
x.appendString(" world!");
return x;
}
To na pewno się nie skompiluje: oprócz appendString()
tego, że nie jest const
operacją, funkcja usuwa const
kwalifikator z odwołania do typu, który wymaga znaku const_cast
.
[*] Spodziewam się, że istnieje jakiś zniekształcony sposób, ale teraz jesteśmy w królestwie jednego programisty, który próbuje sabotować drugiego, robiąc „sprytne” rzeczy.
const
dekorację jako znaczącą, więc otrzymujesz zniekształcenia, takie jak aliasy lub rzutowania, aby ukryć ostrzeżenia, ale w wyniku tych zniekształceń nie ma zmian w zachowaniu programu.const
w Celu C nadal może być przydatne stwierdzenie, że wskaźnik do obiektu nigdy nie jest przypisany do wskazywania na inny obiekt . To znaczy,NSString * const x
że wiesz, żex
zawsze będzie to ten sam ciąg, a nie inny ciąg.Jeśli chodzi o Cel C - nie programuję w nim, więc nie mogę odpowiedzieć na pytanie. Pytanie, na które mogę odpowiedzieć, brzmi: „Czy ludzie powinni
const
dużo korzystać podczas programowania w Celu C?” - ten jest definitywnym „Tak”.Constness jest zasadniczo funkcją bezpieczeństwa oprogramowania, która służy do zwiększenia niezawodności i łatwości konserwacji programów. Wielu programistów dorasta, nie doceniając wartości
const
s, dopóki pewnego dnia wydarzy się coś złego i będą mieli moment „Ah ha” - „Och, do tegoconst
się używa”. Jest całkowicie możliwe napisanie programu bez stałych, jest praktycznie niemożliwe, aby taki program był niezawodny.Wiele próbek kodu nie jest tak naprawdę programami, a jedynie fragmentami zaprojektowanymi tak, aby pokazywały określoną funkcję. Nie używają,
const
ponieważ odwraca to uwagę od miejsca, w którym próbka jest próbowana. Innym typem kodu, który widzisz, jest kod napisany przez niedoświadczonych programistów, którzy opierają swoje działania na przykładach, których się nauczyli, lub tych, którzy wiedzą o stałych i są zbyt leniwi, aby z nich korzystać.źródło
Od bardzo dawna nie używałem celu-c.
Zastanawiam się jednak, dlaczego żadne ciało nie wspomina o tym aspekcie.
Cel-c ma już coś innego związanego ze stałą. Zmienność
Na przykład Nstring * wskaże stały ciąg. Jeśli chcesz ciąg, który możesz modyfikować, używasz NMutableString lub czegoś podobnego. NMutableString zapewni dodatkowe metody, które pozwolą ludziom modyfikować ciąg.
A jeśli chcesz, aby sam wskaźnik był stały. Nigdy nie muszę się tym martwić, kodując bardzo duży projekt.
Myślę więc, że właśnie dlatego.
źródło