Ostatnia constoznacza, że funkcja Method3nie modyfikuje niezmiennych elementów swojej klasy.
const int* constoznacza stały wskaźnik do stałej int: tj. wskaźnik, którego nie można zmienić, do int, którego nie można zmienić: jedyna różnica między tym a const int&polega na tym, że może byćnull
const int* const&oznacza odniesienie do stałego wskaźnika do stałej int. Zazwyczaj wskaźniki nie są przekazywane przez odniesienie; const int* &ma więcej sensu, ponieważ oznaczałoby to, że wskaźnik można zmienić podczas wywołania metody, co byłoby jedynym powodem, dla którego widzę, aby przekazać wskaźnik przez odniesienie, const int* const&jest do wszystkich intencji i celów takie same, const int* constz wyjątkiem tego, że jest prawdopodobnie mniej wydajne Ponieważ wskaźniki są zwykłymi starymi typami danych (POD) i generalnie powinny być przekazywane przez wartość.
# 5 mówi, że cała deklaracja funkcji po lewej stronie to const, co oznacza, że jest to koniecznie funkcja składowa, a nie funkcja wolna.
# 4 mówi, że wskaźnik po lewej stronie to const(nie można go zmienić, aby wskazywał na inny adres).
# 3 mówi, że po intlewej stronie jest const(nie można go zmienić, aby miał inną wartość).
# 2 mówi, że wskaźnik po lewej to const.
# 1 mówi, że intpo lewej stronie jest const.
Łącząc to wszystko razem, możesz to odczytać jako constfunkcję składową Method3o nazwie, która pobiera odwołanie do constwskaźnika do int const(lub const int, jeśli wolisz) i zwraca constwskaźnik do int const( const int).
Przede wszystkim const Tjest odpowiednikiem T const.
const int* constjest zatem równoważne z int const * const.
Czytając wyrażenia z dużą ilością consttokenów i wskaźników, zawsze staraj się czytać je od prawej do lewej (po zastosowaniu powyższej transformacji). W tym przypadku wartość zwracana jest wskaźnikiem stałej do stałejint . Samo tworzenie wskaźnika nie constma tutaj sensu, ponieważ zwracana wartość nie jest lwartością, którą można by zmodyfikować. Wskazanie constjednak gwarantuje, że wywołujący nie może modyfikować int(lub tablicy ints) zwróconej przez Method3.
const int*const&staje się int const*const&, więc jest to odniesienie do stałej wskaźnika do stałejint . Przekazywanie wskaźnika do stałej przez referencje męskie również nie ma sensu - nie możesz modyfikować wartości, do której się odwołujesz, ponieważ wskaźnik jest, consta referencje i wskaźniki zajmują taką samą pamięć, więc nie ma również żadnych oszczędności miejsca.
Ostatnia constwskazuje, że metoda nie modyfikuje thisobiektu. thisWskaźnik w organizmie metoda będzie miał (teoretyczna) oświadczenie T const * const this. Oznacza to, że const T*obiekt będzie mógł wywołać T::Method3().
Głosowanie nad tym (i podobną odpowiedzią ildjarna), częściowo po to, aby podkreślić, że całość ma więcej sensu, jeśli nie umieścisz pierwszych liter na początku constfrazy. Właśnie dlatego uważam, że umieszczanie go w tym miejscu jest złą praktyką const, mimo że język na to pozwala, i jest to najpowszechniejsze użycie.
TED
12
Łatwym sposobem na zapamiętanie zasad programu constjest myślenie o tym w ten sposób: constdotyczy rzeczy po lewej stronie, chyba że nic nie ma po lewej stronie.
Tak więc w przypadku const int * constpierwszej stałej nie ma nic po lewej stronie, więc odnosi się do, inta druga ma coś po lewej stronie, więc odnosi się do wskaźnika.
Ta reguła mówi również, co by się stało, gdybyś miał const int const *. Ponieważ obie const mają zastosowanie do inttego wyrażenia, jest zbędne, a zatem nieważne.
const/* don't modify the int or array of ints' value(s) */int*const/* as a retval, ignored. useless declaration */Method3(const/* don't modify the int or array of ints' value(s) */int*const/* don't modify the pointer's value, the address to which `pointer` points to. e.g. you cannot say `++pointer` */&)const;/* this method does not modify the instance/object which implements the method */
Lubię używać metody "zegara" lub "spirali", gdzie zaczynając od nazwy identyfikatora (w tym przypadku Method3) czytasz tam iz powrotem od lewej do prawej, z powrotem do lewej itd. W celu dekodowania konwencje nazewnictwa. const int* const Method3(const int* const&) constJest to więc metoda klasy, która nie zmienia żadnych składowych klasy (jakiejś nienazwanej klasy) i przyjmuje stałe odwołanie do wskaźnika, który wskazuje na stałą, inti zwraca stały wskaźnik do stałej int.
Łatwym sposobem na zapamiętanie stałej w C ++ jest widok kodu w postaci:
XXX const;const YYY;
XXX, YYY będzie składnikiem stałym w XXX constpostaci:
function ( def var )const;------#1*const;------#2
const YYY Formularz:
constint;------#3constdouble;
Ludzie zwykle używają tych typów. Kiedy "const&"gdzieś widzisz , nie czuj się zdezorientowany, const opisuje coś przed sobą. więc odpowiedź na ten problem jest teraz oczywista.
Chcę tylko wspomnieć, że const int* const&jest to rzeczywiście stałe odniesienie do const int*. Na przykład:
int i =0;int j =1;int* p =&i;int* q =&j;constint*const& cpref = p;
cpref = q;//Error: assignment of read-only reference 'cpref'
Dotyczy to również int* const&, co oznacza: „Stałe odniesienie do int*”.
Ale const int*&jest to niestałe odniesienie do const int*.
Mam nadzieję że to pomoże.
const # 1: wskaźnik zwrócony przez Method3 odnosi się do stałej int.
const # 2: Wartość wskaźnika zwracana przez samą funkcję to const. Jest to bezużyteczna stała (choć poprawna gramatycznie), ponieważ wartość zwracana przez funkcję nie może być wartością l.
const # 3: typ wskaźnika przekazany przez odniesienie do funkcji wskazuje na stałą int.
const # 4: Wartość wskaźnika przekazana przez odniesienie do funkcji jest sama w sobie wskaźnikiem do stałej. Deklarowanie wartości, która jest przekazywana do funkcji jako const normalnie byłoby bezcelowe, ale ta wartość jest przekazywana przez odwołanie, więc może mieć znaczenie.
const # 5: Funkcja (prawdopodobnie funkcja składowa) jest stała, co oznacza, że nie można (a) przypisywać nowych wartości żadnym członom obiektu, którego jest częścią lub (b) wywoływać funkcji niebędącej składową stałą na obiekcie lub którymkolwiek z jego członków.
const na końcu metody znajduje się kwalifikator oznaczający, że stan obiektu nie zostanie zmieniony.
const int*const&oznacza otrzymywanie przez odwołanie wskaźnika do stałej lokalizacji. Nie może się zmienić, aby wskazywać inną lokalizację, ani zmienić wartości, na którą wskazuje.
const int*const jest wartością zwracaną, która jest również stałym wskaźnikiem do stałej lokalizacji.
Kilka przykładów może być fajnych, aby zademonstrować tę koncepcję, im więcej, tym lepsze imho.
classTestClass{private:int iValue;int* oValuePtr;int& oValueRef;public:intTestClass::ByValMethod1(intValue){// Value can be modifiedValue++;// iValue can be modified
iValue =Value;
iValue +=1;// Return value can be modifiedreturn++iValue;}intTestClass::ByValMethod2(constintValue){// Value *cannot* be modified// Variable is const variableValue++;// iValue can be modified
iValue =Value;
iValue +=1;// Return value can be modifiedreturn++iValue;}constintTestClass::ByValMethod3(intValue){// Value can be modifiedValue++;// iValue can be modified
iValue =Value;
iValue +=1;// Return value can be modifiedreturn++iValue;}constintTestClass::ByValMethod4(constintValue){// Value *cannot* be modified// Variable is const variableValue++;// iValue can be modified
iValue =Value;
iValue +=1;// Return value can be modifiedreturn++iValue;}constintTestClass::ByValMethod5(constintValue)const{// Value *cannot* be modified// Variable is const variableValue++;// iValue *cannot* be modified// Access through a const object
iValue =Value;
iValue +=1;// Return value *cannot* be modified// Access through a const objectreturn++iValue;}int&TestClass::ByRefMethod1(int&Value){// Value can be modifiedValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}int&TestClass::ByRefMethod2(constint&Value){// Value *cannot* be modified// Variable is const variableValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}constint&TestClass::ByRefMethod3(int&Value){// Value can be modifiedValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}constint&TestClass::ByRefMethod4(constint&Value){// Value *cannot* be modified// Variable is const variableValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}constint&TestClass::ByRefMethod5(constint&Value)const{// Value *cannot* be modified// Variable is const variableValue++;// oValueRef can be modified
oValueRef =Value;
oValueRef +=1;// Return value can be modifiedreturn++oValueRef;}int*TestClass::PointerMethod1(int*Value){// Value can be modifiedValue++;// oValuePtr can be assigned
oValuePtr =Value;// oValuePtr can be modified
oValuePtr +=1;// Return value can be modifiedreturn++oValuePtr;}int*TestClass::PointerMethod2(constint*Value){// Value can be modifiedValue++;// oValuePtr cannot be assigned// const int* to int*
oValuePtr =Value;// oValuePtr can be modified
oValuePtr +=1;// Return value can be modifiedreturn++oValuePtr;}constint*TestClass::PointerMethod3(int*Value){// Value can be modifiedValue++;// oValuePtr can be assigned
oValuePtr =Value;// iValue can be modified
oValuePtr +=1;// Return value can be modifiedreturn++oValuePtr;}constint*TestClass::PointerMethod4(constint*Value){// Value cannot be modifiedValue++;// oValuePtr *cannot* be assigned// const int* to int*
oValuePtr =Value;// oValuePtr can be modified
oValuePtr +=1;// Return value can be modifiedreturn++oValuePtr;}constint*TestClass::PointerMethod5(constint*Value)const{// Value can be modified++Value;// oValuePtr *cannot* be assigned// const int* to int* const// Access through a const object
oValuePtr =Value;// oValuePtr *cannot* be modified// Access through a const object
oValuePtr +=1;// Return value *cannot* be modifiedreturn++oValuePtr;}};
Odpowiedzi:
Przeczytaj to: https://isocpp.org/wiki/faq/const-correctness
Ostatnia
const
oznacza, że funkcjaMethod3
nie modyfikuje niezmiennych elementów swojej klasy.const int* const
oznacza stały wskaźnik do stałej int: tj. wskaźnik, którego nie można zmienić, do int, którego nie można zmienić: jedyna różnica między tym aconst int&
polega na tym, że może byćnull
const int* const&
oznacza odniesienie do stałego wskaźnika do stałej int. Zazwyczaj wskaźniki nie są przekazywane przez odniesienie;const int* &
ma więcej sensu, ponieważ oznaczałoby to, że wskaźnik można zmienić podczas wywołania metody, co byłoby jedynym powodem, dla którego widzę, aby przekazać wskaźnik przez odniesienie,const int* const&
jest do wszystkich intencji i celów takie same,const int* const
z wyjątkiem tego, że jest prawdopodobnie mniej wydajne Ponieważ wskaźniki są zwykłymi starymi typami danych (POD) i generalnie powinny być przekazywane przez wartość.źródło
Łatwiej jest zrozumieć, jeśli przepiszesz to jako całkowicie równoważne
następnie przeczytaj go od prawej do lewej.
# 5 mówi, że cała deklaracja funkcji po lewej stronie to
const
, co oznacza, że jest to koniecznie funkcja składowa, a nie funkcja wolna.# 4 mówi, że wskaźnik po lewej stronie to
const
(nie można go zmienić, aby wskazywał na inny adres).# 3 mówi, że po
int
lewej stronie jestconst
(nie można go zmienić, aby miał inną wartość).# 2 mówi, że wskaźnik po lewej to
const
.# 1 mówi, że
int
po lewej stronie jestconst
.Łącząc to wszystko razem, możesz to odczytać jako
const
funkcję składowąMethod3
o nazwie, która pobiera odwołanie doconst
wskaźnika doint const
(lubconst int
, jeśli wolisz) i zwracaconst
wskaźnik doint const
(const int
).(Uwaga nr 2 jest całkowicie zbędna ).
źródło
Przede wszystkim
const T
jest odpowiednikiemT const
.const int* const
jest zatem równoważne zint const * const
.Czytając wyrażenia z dużą ilością
const
tokenów i wskaźników, zawsze staraj się czytać je od prawej do lewej (po zastosowaniu powyższej transformacji). W tym przypadku wartość zwracana jest wskaźnikiem stałej do stałejint
. Samo tworzenie wskaźnika nieconst
ma tutaj sensu, ponieważ zwracana wartość nie jest lwartością, którą można by zmodyfikować. Wskazanieconst
jednak gwarantuje, że wywołujący nie może modyfikowaćint
(lub tablicyint
s) zwróconej przezMethod3
.const int*const&
staje sięint const*const&
, więc jest to odniesienie do stałej wskaźnika do stałejint
. Przekazywanie wskaźnika do stałej przez referencje męskie również nie ma sensu - nie możesz modyfikować wartości, do której się odwołujesz, ponieważ wskaźnik jest,const
a referencje i wskaźniki zajmują taką samą pamięć, więc nie ma również żadnych oszczędności miejsca.Ostatnia
const
wskazuje, że metoda nie modyfikujethis
obiektu.this
Wskaźnik w organizmie metoda będzie miał (teoretyczna) oświadczenieT const * const this
. Oznacza to, żeconst T*
obiekt będzie mógł wywołaćT::Method3()
.źródło
const
frazy. Właśnie dlatego uważam, że umieszczanie go w tym miejscu jest złą praktykąconst
, mimo że język na to pozwala, i jest to najpowszechniejsze użycie.Łatwym sposobem na zapamiętanie zasad programu
const
jest myślenie o tym w ten sposób:const
dotyczy rzeczy po lewej stronie, chyba że nic nie ma po lewej stronie.Tak więc w przypadku
const int * const
pierwszej stałej nie ma nic po lewej stronie, więc odnosi się do,int
a druga ma coś po lewej stronie, więc odnosi się do wskaźnika.Ta reguła mówi również, co by się stało, gdybyś miał
const int const *
. Ponieważ obie const mają zastosowanie doint
tego wyrażenia, jest zbędne, a zatem nieważne.źródło
źródło
Lubię używać metody "zegara" lub "spirali", gdzie zaczynając od nazwy identyfikatora (w tym przypadku
Method3
) czytasz tam iz powrotem od lewej do prawej, z powrotem do lewej itd. W celu dekodowania konwencje nazewnictwa.const int* const Method3(const int* const&) const
Jest to więc metoda klasy, która nie zmienia żadnych składowych klasy (jakiejś nienazwanej klasy) i przyjmuje stałe odwołanie do wskaźnika, który wskazuje na stałą,int
i zwraca stały wskaźnik do stałejint
.Mam nadzieję że to pomoże,
Jason
źródło
Łatwym sposobem na zapamiętanie stałej w C ++ jest widok kodu w postaci:
XXX, YYY będzie składnikiem stałym w
XXX const
postaci:const YYY
Formularz:Ludzie zwykle używają tych typów. Kiedy
"const&"
gdzieś widzisz , nie czuj się zdezorientowany, const opisuje coś przed sobą. więc odpowiedź na ten problem jest teraz oczywista.źródło
Chcę tylko wspomnieć, że
const int* const&
jest to rzeczywiście stałe odniesienie doconst int*
. Na przykład:Dotyczy to również
int* const&
, co oznacza: „Stałe odniesienie doint*
”.Ale
const int*&
jest to niestałe odniesienie doconst int*
.Mam nadzieję że to pomoże.
źródło
Czytanie od prawej do lewej ułatwia zrozumienie modyfikatorów.
Metoda const, która przyjmuje odwołanie do stałego wskaźnika do stałej int o nazwie,
Method3
która zwraca wskaźnik do stałej wartości stałej int.mutable
)źródło
const # 1: wskaźnik zwrócony przez Method3 odnosi się do stałej int.
const # 2: Wartość wskaźnika zwracana przez samą funkcję to const. Jest to bezużyteczna stała (choć poprawna gramatycznie), ponieważ wartość zwracana przez funkcję nie może być wartością l.
const # 3: typ wskaźnika przekazany przez odniesienie do funkcji wskazuje na stałą int.
const # 4: Wartość wskaźnika przekazana przez odniesienie do funkcji jest sama w sobie wskaźnikiem do stałej. Deklarowanie wartości, która jest przekazywana do funkcji jako const normalnie byłoby bezcelowe, ale ta wartość jest przekazywana przez odwołanie, więc może mieć znaczenie.
const # 5: Funkcja (prawdopodobnie funkcja składowa) jest stała, co oznacza, że nie można (a) przypisywać nowych wartości żadnym członom obiektu, którego jest częścią lub (b) wywoływać funkcji niebędącej składową stałą na obiekcie lub którymkolwiek z jego członków.
źródło
const
na końcu metody znajduje się kwalifikator oznaczający, że stan obiektu nie zostanie zmieniony.const int*const&
oznacza otrzymywanie przez odwołanie wskaźnika do stałej lokalizacji. Nie może się zmienić, aby wskazywać inną lokalizację, ani zmienić wartości, na którą wskazuje.const int*const
jest wartością zwracaną, która jest również stałym wskaźnikiem do stałej lokalizacji.źródło
Kilka przykładów może być fajnych, aby zademonstrować tę koncepcję, im więcej, tym lepsze imho.
Mam nadzieję, że to pomoże!
źródło