2013-03-14 10 views
8

Moje pytanie jest o różnicę między:C++ dwie wersje przeciążenia operatora indeks

const T& operator[](const int nIndex) const; 

oraz:

T& operator[](const int nIndex); 

Dlaczego muszę oboje zdefiniowane w klasie, jaki jest cel? Czy to drugie nie wystarczy?

+0

możliwy duplikat [co oznacza const w C++ w różnych miejscach] (http://stackoverflow.com/questions/10482455/what-does-const-mean-in-c-in-different-places) – juanchopanza

Odpowiedz

15

Deklaracja funkcji członka z const w końcu to, że funkcja pozwala na miano nawet na obiekcie const. Ma to sens tylko dla funkcji składowych, które nie modyfikują stanu obiektu.

Załóżmy, że klasa, która powoduje przeciążenie tych operatorów, nazywa się X. Przypuszczalnie zachowuje się trochę jak pojemnik, dając dostęp do elementów, które zawiera przez to operator[].

Teraz powiedzmy, że użytkownik chce użyć const X:

const X x = /* fill it */; 
use(x[0]); 

Jeżeli użytkownik móc to zrobić? Prawdopodobnie. Jeśli chcą mieć niezmienny pojemnik, pozwól mu go mieć. Jeśli nie dostarczysz wersji , nie będą mogli tego zrobić. W końcu nie próbują modyfikować kontenera, tylko patrzą na jego zawartość.

Dlaczego warto teraz odwołać się do wersji const z numerem referencyjnym ? Ponieważ musi. Zwraca referencję do członka samej klasy. Jeżeli pojemnik był const i wrócił niebędącą const odniesienia, rozmówca będzie mógł modyfikować swoje wewnętrzne tylko za pomocą tego operatora:

const X x = /* fill it */; 
x[0].modify(); 

Och, możemy zmodyfikować stan x mimo to const. To byłoby złe, a kompilator nawet nie pozwoli ci tego zrobić.

+0

I dodałbym, że 2 podobne przeciążone metody (const i non const) są często podstawowymi elementami w C++ –

+0

@ftfbitbit: głupia obserwacja: czy rozumiem poprawnie, że wciąż muszę zdefiniować dwa oddzielne ciała wersji const i non const operatorów i że te organy będą dokładnie takie same? Zasadniczo, coś podobnego do powrotu MyDataStructure [nIndex]? –

+1

@SimonRighley Tak, musisz zdefiniować oba. Możesz * zdefiniować * wersję nie będącą 'konną' pod względem wersji' const', ale wtedy musisz wykonać 'const_cast'. Lepiej mieć tylko duplikat wdrożenia. –

2

Jeśli obiekt, do którego wchodzisz, to const, nie możesz go modyfikować. Kompilator nie pozwoliłby na wywołanie wersji funkcji innej niż const.

const vector<int> mints; 

mints[3] = 5; // not allowed by compiler 
3

Są funkcje członka klasy, a wersja wybiera się na podstawie tego, czy stosowane jako klasa w kontekście const.

Ta wersja zostanie wywołana, gdy [] zostanie użyty na obiekcie w kontekście const. Zachowuje on wartość zwracanego elementu.

const T& operator[](const int nIndex) const; 

Wersja ta zostanie wywołana gdy [] jest używany na niebędącego const obiektu. Określa ona, że ​​gdy obiekt nie jest const, dostaniesz element, który można modyfikować, dzięki czemu kod jak myObject[0] = 10;

T& operator[](const int nIndex); 
2

Pierwszy

const T & operatora [] (const Int nIndex) const;

jest metodą (funkcją) stałą, tzn. Gwarantuje, że nie zmieni żadnej z zmiennych członków klasy (chyba że jest zmienna).

Zwraca także stały obiekt, co oznacza, że ​​można wywołać tylko stałą funkcję, tzn. Można wywoływać tylko funkcje, które mają const na końcu, podobne do tego powyżej.

T & operator [] (const int nIndex);

Ta metoda może zmienić zmienne składowe i zwraca obiekt, który może wywoływać dowolne metody klas.

Potrzebujemy ich obu, ponieważ obiekt stały użyłby metody stałej, a nie stała, by użyć drugiego.

Powiązane problemy