Jako początkujący programista C ++ istnieją pewne konstrukcje, które nadal wydają mi się bardzo niejasne, jednym z nich jest const
. Możesz go używać w tak wielu miejscach i przy tak wielu różnych efektach, że dla początkującego prawie niemożliwe jest wyjść z życiem. Czy jakiś guru C ++ wyjaśni raz na zawsze różne zastosowania i czy i / lub dlaczego ich nie używać?
129
Odpowiedzi:
Próbuję zebrać kilka zastosowań:
Powiązanie niektórych tymczasowych z odniesieniem do const, aby wydłużyć jego żywotność. Odniesienie może być bazą - a jego destruktor nie musi być wirtualny - właściwy destruktor jest nadal nazywany:
Wyjaśnienie za pomocą kodu:
Ta sztuczka jest używana w klasie narzędziowej ScopeGuard Alexandrescu. Gdy obiekt tymczasowy znajdzie się poza zakresem, Destruktor klasy Derived jest wywoływany poprawnie. W powyższym kodzie brakuje kilku drobnych szczegółów, ale to jest wielka sprawa.
Użyj const, aby powiedzieć innym metodom, że nie zmienią stanu logicznego tego obiektu.
Użyj const dla klas kopiowania przy zapisie , aby kompilator pomógł ci zdecydować, kiedy nie chcesz kopiować.
Objaśnienie : Możesz chcieć udostępniać dane podczas kopiowania, o ile dane obiektu oryginalnego i kopiowanego pozostają takie same. Gdy jeden z obiektów zmieni dane, potrzebujesz teraz dwóch wersji: jednej dla oryginału i jednej dla kopii. Oznacza to, że kopiowanie na zapis do obu obiektów, tak, że teraz obie mają własną wersję.
Używając kodu :
Powyższy fragment kodu wyświetla ten sam adres na moim GCC, ponieważ używana biblioteka C ++ implementuje kopiowanie przy zapisie
std::string
. Oba łańcuchy, mimo że są odrębnymi obiektami, współużytkują tę samą pamięć dla swoich danych. Utworzenie wartościb
innej niż const będzie preferować wersjęoperator[]
inną niż const, a GCC utworzy kopię zapasowego bufora pamięci, ponieważ możemy go zmienić i nie może to wpływać na danea
!Aby konstruktor kopiujący mógł wykonać kopie z obiektów stałych i tymczasowych :
Do tworzenia stałych, których trywialnie nie można zmienić
Do przekazywania dowolnych obiektów przez odniesienie zamiast według wartości - aby zapobiec potencjalnie kosztownemu lub niemożliwemu przekazywaniu wartości bocznej
źródło
W C ++ są naprawdę 2 główne zastosowania const.
Wartości stałe
Jeśli wartość ma postać zmiennej, składowej lub parametru, który nie będzie (lub nie powinien) być zmieniany podczas swojego życia, należy oznaczyć ją jako stałą. Pomaga to zapobiegać mutacjom na obiekcie. Na przykład w poniższej funkcji nie muszę zmieniać przekazanej instancji Student, więc oznaczam ją jako const.
Dlaczego miałbyś to zrobić. O wiele łatwiej jest rozumować algorytm, jeśli wiesz, że podstawowe dane nie mogą się zmienić. „const” pomaga, ale nie gwarantuje, że zostanie to osiągnięte.
Oczywiście drukowanie danych na żądanie nie wymaga zbytniego myślenia :)
Oznaczanie metody składowej jako const
W poprzednim przykładzie oznaczyłem Student jako const. Ale skąd C ++ wiedział, że wywołanie metody GetName () na uczniu nie spowoduje mutacji obiektu? Odpowiedź jest taka, że metoda została oznaczona jako const.
Oznaczenie metody „const” ma 2 rzeczy. Przede wszystkim mówi C ++, że ta metoda nie spowoduje mutacji mojego obiektu. Po drugie, wszystkie zmienne składowe będą teraz traktowane tak, jakby były oznaczone jako stałe. Pomaga to, ale nie zapobiega modyfikowaniu instancji Twojej klasy.
To niezwykle prosty przykład, ale miejmy nadzieję, że pomoże on odpowiedzieć na Twoje pytania.
źródło
Zwróć uwagę, aby zrozumieć różnicę między tymi 4 deklaracjami:
Następujące 2 deklaracje są identyczne pod względem semantycznym. Można zmienić gdzie ccp1 i CCP2 punkt, ale nie można zmienić rzeczy oni wskazującego.
Następnie wskaźnik jest stały, więc aby był sensowny, musi zostać zainicjalizowany, aby wskazywał na coś. Nie możesz wskazać na coś innego, jednak to, na co wskazuje, można zmienić.
Na koniec łączymy te dwa elementy - więc wskazywana rzecz nie może być modyfikowana, a wskaźnik nie może wskazywać nigdzie indziej.
Reguła spirali zgodnej z ruchem wskazówek zegara może pomóc rozplątać deklarację http://c-faq.com/decl/spiral.anderson.html
źródło
Na marginesie, gdy czytam tutaj , warto to zauważyć
źródło