Po 15 latach C ++ wciąż nie nauczyłem się kochać używając const. Rozumiem, że jest użyteczny, ale tak naprawdę nigdy nie byłem w sytuacji, w której bycie nieustępliwym uniknęłoby problemu, z którym miałem do czynienia.
Jak więc pokochałeś zalety consts?
Odpowiedzi:
Cóż, nie byłem przekonany, dopóki nie spróbowałem przyjąć filozofii.
Najpierw zacząłem od umieszczenia
const
argumentów moich najbardziej podstawowych członków klasy i funkcji członkowskich tylko do odczytu.Stamtąd nie mogłem już kompilować. Potem wytrwałem, wchodząc w kod przy użyciu tych podstawowych klas, sprawdzając, czy wcześniej
const
dodane dodatki były naprawdę uzasadnione w porównaniu do ich wykorzystania. Pomogło mi to naprawić kilka błędów po drodze, dodając ciągłość do innych części kodu.To jest zaraźliwe. Większość kodu zyskała jeszcze większą spójność i łatwiej mi było go debugować, ponieważ daje pewność, że kompilator zatrzyma cię, jeśli zaczniesz modyfikować coś, czego nie powinieneś.
Gdy ponownie uruchomiłem aplikację, była szybsza (musiałam zmienić niektóre algorytmy, które, jak odkryłam, nie były odpowiednie do tego zadania), z dużo mniejszą liczbą błędów i łatwiejsza do zrozumienia podczas czytania kodu.
Byłem przekonany.
Teraz uważam, że jest jeszcze lepiej, gdy używasz wielu asercji oprócz constness, ponieważ to daje poczucie pewności, kiedy musisz napisać nowy kod lub zmodyfikować bieżący kod. Wiesz, że kompilator zatrzyma cię w razie potrzeby. Pozwala zapomnieć o sprawdzaniu wszystkiego, czego nie należy modyfikować, a wtedy masz więcej czasu na myślenie bardziej biznesowe lub architektoniczne.
źródło
const
nawet dla zmiennej lokalnej, o której wiem, że nie będę musiał jej zmieniać, w ten sposób podczas czytania kodu mogę przeskoczyć nad aif
lub afor
lub whatelse: moja zmienna jest stała, ja wiedz, że to się nie zmieni! Optymalizacje nie mniej mnie obchodziły, ale mam ograniczony mózg, a kilka poziomów wcięć + stała poprawność bardzo pomaga!Nigdy nie byłem zwolennikiem programowania obiektowego, a jeśli cokolwiek się urosło, tym więcej dowiaduję się o programowaniu w ogóle. Jak już studiował różne paradygmaty programowania, zdałem sobie sprawę, że niezmienność jest jednym z centralnych pojęć projektowania programu, wpływając oprogramowanie napisane według dowolnego filozofii. Jest to niezwykle ważne w programowaniu funkcjonalnym, z implikacjami optymalizacji i współbieżności oprócz prostych gwarancji bezpieczeństwa.
Zasadniczo wszystko, co może być niezmienne, prawdopodobnie powinno być, chyba że masz dobry powód do zmiany stanu. Z mojego doświadczenia wynika, że pisanie programów w dowolnym języku w celu osiągnięcia tego celu prowadzi do bezpieczniejszego, lepszego kodu. W
const
razie potrzeby nie masz nic do stracenia - niezmienność jest darmowa!(Nawiasem mówiąc, zastanawiałem się nad stworzeniem rozwidlenia GCC dla dialektu C ++, w którym wszystkie typy
const
nie są wyraźnie określone jakomutable
. Jeśli istnieje wsparcie dla takiej rzeczy, całkowicie zobowiązuję się do jej utrzymania i używania.)Z punktu widzenia OO niezmienność wymusza enkapsulację, uniemożliwiając nieograniczony dostęp do zapisu. Zmniejsza to sprzężenie między klasami, ponieważ obiekty niezmienne muszą w pełni zarządzać własnym stanem i tym samym zachowywać się jak zwykłe wartości. Const poprawność znacznie ułatwia proces sprawdzania poprawności programu, szczególnie w kontekście programowania współbieżnego. Dzięki semantyce referencji C ++ i semantyce referencji do wartości C ++ 0x możesz korzystać z niezmiennych obiektów bez obawy o koszty związane z kopiowaniem ich w dowolnym miejscu. Co więcej, kompilator może pracować z niesamowitą magią optymalizacji, jeśli pracujesz z najczęściej niezmiennymi obiektami.
Wiem, że pisanie
const
wszędzie jest do bani , ale szybko się do tego przyzwyczajasz, a korzyści stają się z czasem widoczne pod względem niezawodności i łatwości konserwacji. Nie jestem genialnym pisarzem i wydaje się, że udowodnienie tego jest trudnym zadaniem, ale wiem, że stała poprawność była bardzo pomocna dla mnie jako programisty przy projektowaniu i wdrażaniu programów i myślę, że doświadczenie jest najlepszy nauczyciel pod tym względem.źródło
mutable
, ponieważ ma to wyraźne znaczenie pod względem stałej poprawności. Oznacza to, że ten obiekt danych może się zmieniać w sposób, który nie wpływa na zachowanie obiektu, i umożliwia takie rzeczy, jak buforowanie odpowiedzi. Utwórz inne słowo kluczowe.mutable
logiki jest logicznym wyborem.void alter(mutable Point&)
ma sens, podobnie jakmutable int foo
w przypadku zmiennej lokalnej, i żaden z tych konfliktów nie jest związany z istniejącym językiem ani z istniejącym użyciemmutable
. RównieżObject mutable* mutable
wygląda groźnie wystarczy być ostrzeżenie o tym, czy jest to konieczne lub właściwe.Zaletą stałej poprawności jest to, że nakłada dyscyplinę na program i ułatwia rozumowanie na temat części programu.
Dyscyplina polega na tym, że musisz wiedzieć, gdzie coś może się zmienić. Odpowiednią zaletą jest to, że łatwiej jest zobaczyć, co robi kawałek kodu, gdy można stwierdzić, co może zmienić stan.
źródło
Bycie const poprawnym podkreśla poprawność projektu, który traktuję blisko podobnej kwestii, która nie polega na użyciu operatorów rzutowania; więc nie używanie rzutowania i ciągła poprawność, minimalne użycie zmiennych - wszystkie są wskaźnikami do pomiaru, jak dobry jest projekt ale nie rzeczywistymi narzędziami do rozwiązania ogólnego problemu.
PS: Całkowicie przekonałem się,
const
kiedy zrozumiałem poprawność korzystania z niego;)źródło
Widzę dwa główne powody pisania poprawnego kodu. Jednym z nich jest to, że kompilator jest twoim przyjacielem i za pomocą const pozwalasz mu ostrzegać przed potencjalnymi błędami. Drugim powodem jest to, że poprawność stałej sprawia, że kod jest bardziej czytelny. Na przykład zawsze wiesz, które argumenty funkcji są wejściami, a które wyjściami. Wiesz także, które funkcje składowe modyfikują obiekt, a które nie. Znasz te rzeczy natychmiast, bez konieczności czytania kodu. Zakłada to oczywiście bardzo rozsądne użycie
const_cast
.źródło
Byłem nawrócony, gdy tylko wiedziałem, że to możliwe. To miało dla mnie sens z punktu widzenia „dobrego stylu programowania”. Istnieje wiele powodów, dla których dobrą praktyką jest ciągłe poprawianie:
źródło
Aby podsumować dwa punkty, które zostały omówione w innych odpowiedziach, i dodaj nowy:
const
dokumentuje kod użytkownikom interfejsu API. Tworzy umowę między funkcją a jej wywołującym, że funkcja nie będzie modyfikować swoich parametrów. (Należy pamiętać, żeconst_cast
nie pozwala funkcji na zmianę parametru, pozwala przekazać ten parametr do innych funkcji, które nie modyfikują swoich parametrów, ale zapomniałyconst
adnotacji.) Jest to również przydatne w funkcjach / pętli / etc, ponieważ pomaga znacznie zrozumieć tak samo jak niezmiennik pętli.const
dokumentuje twoje zamiary w kompilatorze. Znalezienie błędów w czasie kompilacji jest zawsze lepsze niż czekanie na uruchomienie tego fragmentu kodu.const
jest niezbędny do bezpiecznego polimorfizmu typu. Wskaźniki (we wszystkich swoich postaciach, nie tylko surowe wskaźniki) są kowariantne tylko wtedy, gdy sąconst
(Uwaga: nie to samo, co „wskaźnik do stałej”). Kowariancja wymaga interfejsu tylko do odczytu, a kontrawariancja wymaga interfejsu tylko do odczytu.Drugi z nich nauczyłem się pierwszy. Zacząłem
const
od samego celu wskaźnika i parametrów referencyjnych, dopóki nie zacząłem dostrzegać korzyści z wcześniejszego wychwytywania błędów i używania go na lokalnych, itp.Potem dowiedziałem się, że większość
#define
s można zastąpić (w C ++) stałymi globalnymi, z dodatkowymi korzyściami bezpieczeństwa typu. Więc też go tam wykorzystałem.W końcu wziąłem klasę na temat systemów typów i rachunku lambda i dowiedziałem się, że
const
i nietypoweconst
są zasadniczo różne (ponieważ obsługują różne operacje), i od tego czasu nigdy nawet nie rozważałem pisania kodu C ++ bez intensywnego użyciaconst
.źródło
Oto moje 5 centów tego, o czym inni nie wspominali. Przekazując zmienne, nie chcesz przekazywać wartości, chyba że naprawdę potrzebujesz, aby uniknąć dodatkowych konstrukcji, zniszczeń i kopii. Tak więc, chyba że naprawdę musisz przekazać wartość, używanie referencji wszędzie, nawet jeśli nie chcesz zmieniać przekazywanej wartości, to znaczny wzrost wydajności. Z tego powodu, gdy masz funkcje pobierające odwołania do wszystkich jej argumentów, musisz powiadomić program wywołujący, czego funkcja nie będzie modyfikować.
To ta sama zasada, ale chciałem tylko dodać praktyczny powód użycia const.
źródło