Ile i jakie są zastosowania "const" w C++?

Jako początkujący programista C++ istnieją pewne konstrukcje, które wciąż wydają mi się bardzo niejasne, jedną z nich jest const. Możesz go używać w tak wielu miejscach i z tak wieloma różnymi efektami, które są prawie niemożliwe, aby początkujący wyszedł żywy. Czy jakiś Guru C++ wyjaśni raz na zawsze różne zastosowania i czy i / lub dlaczego ich nie używać?

 112
Author: BradleyDotNET, 2009-01-18

4 answers

Próbuje zebrać kilka zastosowań:

Wiązanie jakiegoś tymczasowego odniesienia do const, aby wydłużyć jego żywotność.Nie jest to jednak możliwe, ponieważ nie jest to możliwe, ponieważ nie jest to możliwe, ponieważ nie jest to możliwe.]}

ScopeGuard const& guard = MakeGuard(&cleanUpFunction);

Wyjaśnienie, używając kodu:

struct ScopeGuard { 
    ~ScopeGuard() { } // not virtual
};

template<typename T> struct Derived : ScopeGuard { 
    T t; 
    Derived(T t):t(t) { }
    ~Derived() {
        t(); // call function
    }
};

template<typename T> Derived<T> MakeGuard(T t) { return Derived<T>(t); }

Ten trik jest używany w klasie użytkowej Scopeguard Alexandrescu. Gdy czasownik wychodzi poza zasięg, Destruktor pochodnej jest wywoływany poprawnie. Powyższy kod brakuje kilku drobnych szczegółów, ale w tym tkwi problem.


Użyj const, aby powiedzieć innym metodom, że nie zmienią stanu logicznego tego obiektu.

struct SmartPtr {
    int getCopies() const { return mCopiesMade; }
};

Użyj const dla klas copy-on-write , aby kompilator pomógł Ci zdecydować, kiedy i kiedy nie musisz kopiować.

struct MyString {
    char * getData() { /* copy: caller might write */ return mData; }
    char const* getData() const { return mData; }
};

Explanation: możesz chcieć udostępnić dane podczas kopiowania czegoś tak długo, jak dane oryginalnego i kopiowanego obiektu pozostają to samo. Gdy jeden z obiektów zmieni dane, potrzebujesz teraz dwóch wersji: jednej dla oryginału i jednej dla kopii. Oznacza to, że kopiujesz na zapisujesz do dowolnego obiektu, tak aby oba obiekty miały swoją własną wersję.

użycie kodu :

int main() {
    string const a = "1234";
    string const b = a;
    // outputs the same address for COW strings
    cout << (void*)&a[0] << ", " << (void*)&b[0];
}

Powyższy fragment wyświetla ten sam adres w moim GCC, ponieważ używana biblioteka C++ implementuje kopię przy zapisie std::string. Oba ciągi, mimo że są odrębnymi obiektami, mają tę samą pamięć dla swoich string data. Tworzenie b non-const będzie preferowało wersję operator[] non-const, a GCC utworzy kopię bufora pamięci, ponieważ możemy go zmienić i nie może to wpływać na dane a!

int main() {
    string const a = "1234";
    string b = a;
    // outputs different addresses!
    cout << (void*)&a[0] << ", " << (void*)&b[0];
}

Dla konstruktora kopiującego do wykonywania kopii z obiektów const i tymczasowych :

struct MyClass {
    MyClass(MyClass const& that) { /* make copy of that */ }
};

Do tworzenia stałych, których trywialnie nie można zmienić

double const PI = 3.1415;

Do przekazywania dowolnych obiektów przez odniesienie zamiast o wartości - aby zapobiec ewentualnemu kosztownemu lub niemożliwemu przekazaniu wartości

void PrintIt(Object const& obj) {
    // ...
}

 95
Author: Johannes Schaub - litb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-02 02:13:36

Istnieją naprawdę 2 główne zastosowania const w C++.

Wartości Const

Jeśli wartość jest w postaci zmiennej, elementu lub parametru, który nie będzie (lub nie powinien) być zmieniany podczas swojego życia, należy oznaczyć ją const. Pomaga to zapobiegać mutacjom na obiekcie. Na przykład, w poniższej funkcji nie muszę zmieniać instancji Student przeszedł więc zaznaczam go const.

void PrintStudent(const Student& student) {
  cout << student.GetName();
}
Dlaczego to zrobiłeś? O wiele łatwiej jest rozumować o 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 do cout nie wymaga wiele myślenia:)

Oznaczanie metody prętowej jako const

W poprzednim przykładzie zaznaczyłem Student jako const. Ale skąd C++ wiedział, że wywołanie metody GetName () na studencie nie zmutuje obiektu? Odpowiedź jest taka, że metoda została oznaczona jako const.

class Student {
  public:
    string GetName() const { ... }
};

Oznaczenie a metoda "const" robi 2 rzeczy. Przede wszystkim mówi C++ , że ta metoda nie zmutuje mojego obiektu. Drugą rzeczą jest to, że wszystkie zmienne członkowskie będą teraz traktowane tak, jakby były oznaczone jako const. Pomaga to, ale nie uniemożliwia modyfikowania instancji klasy.

Jest to niezwykle prosty przykład, ale mam nadzieję, że pomoże odpowiedzieć na twoje pytania.

 23
Author: JaredPar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-16 20:23:41

Zwróć uwagę, aby zrozumieć różnicę między tymi 4 deklaracjami:

Poniższe 2 deklaracje są identyczne semantycznie. Możesz zmienić Gdzie ccp1 i ccp2 wskazują, ale nie możesz zmienić tego, na co wskazują.

const char* ccp1;
char const* ccp2;

Następnie, wskaźnik jest const, więc aby mieć znaczenie, musi być zainicjalizowany, aby wskazać na coś. Nie możesz sprawić, by wskazywało na coś innego, jednak to, co wskazuje na , Może zostać zmienione.

char* const cpc = &something_possibly_not_const;

W końcu łączymy dwa - więc rzecz wskazywana nie może być modyfikowana, a wskaźnik nie może wskazywać nigdzie indziej.

const char* const ccpc = &const_obj;

Reguła spirali zgodnie z ruchem wskazówek zegara może pomóc rozwikłać deklarację http://c-faq.com/decl/spiral.anderson.html

 14
Author: Steve Folly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-22 19:35:45

Jako mała notka, jak czytam Tutaj, Warto zauważyć, że

const dotyczy tego, co znajduje się po jego bezpośrednim lewej stronie (poza nie ma tam nic, w takim przypadku odnosi się to do tego, co jest jego bezpośrednio w prawo).

 2
Author: JoePerkins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-11 12:00:37