C++ Const Usage Explanation

const int* const Method3(const int* const&) const;

Czy ktoś może wyjaśnić użycie każdego z const?

 85
Author: pajton, 2011-04-08

12 answers

Przeczytaj to: https://isocpp.org/wiki/faq/const-correctness

Końcowy const oznacza, że funkcja Method3 nie modyfikuje nie mutowalnych członków swojej klasy.

const int* const oznacza stały wskaźnik do stałej int: tj. wskaźnik, który nie może być zmieniony, do int, który nie może być zmieniony: jedyną różnicą między tym i const int& jest to, ż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ększy sens, ponieważ oznaczałoby to, że wskaźnik może być zmieniany podczas wywołania metody, co byłoby jedynym powodem, dla którego mogę zobaczyć, aby przekazać wskaźnik przez odniesienie, const int* const& jest pod każdym względem taki sam jak const int* const z tym wyjątkiem, że jest prawdopodobnie mniej wydajny, ponieważ wskaźniki są zwykłymi starymi typami danych (POD) i powinny być ogólnie przekazywane przez wartość.

 69
Author: briantyler,
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
2016-07-22 14:36:31

Łatwiej będzie zrozumieć, jeśli przepisasz to jako całkowicie równoważne

// v───v───v───v───v───v───v───v───v───v───v───v─┬┐
//                                               ││
//  v──#1    v─#2             v──#3    v─#4      #5
   int const * const Method3(int const * const&) const;

Następnie Przeczytaj od prawej do lewej.

#5 mówi, że cała deklaracja funkcji po lewej stronie to const, co oznacza, że jest to funkcja członkowska, a nie Funkcja wolna.

#4 mówi, że wskaźnik po lewej stronie to const (nie może być zmieniony, aby wskazywać na inny adres).

#3 mówi, że int po lewej jest const (nie można zmienić na mają inną wartość).

#2 mówi, że wskaźnik w lewo to const.

#1 mówi, że int po lewej jest const.

Składając to wszystko razem, możesz odczytać to jako const funkcję member o nazwie Method3, która pobiera odniesienie do const Wskaźnik do int const (lub const int, jeśli wolisz) i zwraca const Wskaźnik do constint const (const int).

 93
Author: ildjarn,
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
2015-02-12 17:42:21

Po pierwsze {[0] } jest równoważne T const.

const int* const jest więc równoważne int const * const.

Podczas czytania wyrażeń z dużą ilością const tokenów i wskaźników, zawsze staraj się odczytać je od prawej do lewej (Po zastosowaniu powyższej transformacji). Tak więc w tym przypadku wartością zwracaną jest wskaźnik const do const int. Tworzenie samego wskaźnika const nie ma tu sensu, ponieważ zwracana wartość nie jest lvalue, który mógłby zostać zmodyfikowany. Making the pointee const gwarantuje jednak, że wywołujący nie może modyfikować int (lub tablicy ints) zwracanej przez Method3.

const int*const& staje się int const*const&, więc jest to odniesienie do wskaźnika const do const int. Przekazywanie wskaźnika const przez referencje nie ma sensu-nie można modyfikować wartości odniesienia, ponieważ wskaźnik wynosi const, A referencje i wskaźniki zajmują jednakowe miejsce, więc nie ma też oszczędności miejsca.

Ostatni const wskazuje, że metoda nie modyfikować obiektu this. Wskaźnik this wewnątrz ciała metody będzie miał (teoretyczną) deklarację T const * const this. Oznacza to, że obiekt const T* będzie mógł wywołać T::Method3().

 21
Author: Alexander Gessler,
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
2011-04-08 17:45:16

Łatwym sposobem na zapamiętanie zasad const jest myślenie o tym w ten sposób: const odnosi się do rzeczy po jej lewej, chyba że nie ma nic po jej lewej.

Więc w przypadku const int * const, pierwszy const nie ma nic po lewej stronie, więc odnosi się do int, a drugi ma coś po lewej stronie, więc odnosi się do wskaźnika.

Ta zasada mówi również, co stanie się w przypadku, gdy masz const int const *. Ponieważ oba const mają zastosowanie do {[3] } to wyrażenie jest zbędne i dlatego nieważne.

 11
Author: Yony,
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
2011-04-08 17:55:31

Lubię używać metody "clock" lub "spiral" gdzie zaczynając od nazwy identyfikatora (w tym przypadku Method3) czytasz tam i z powrotem od lewej do prawej, z powrotem do lewej, itd. w celu dekodowania konwencji nazewnictwa. Tak więc {[1] } jest metodą klasy, która nie zmienia żadnych członków klasy (jakiejś nie nazwanej klasy)i pobiera stałe odniesienie do wskaźnika, który wskazuje na stałą int i zwraca stały wskaźnik do stałej int.

Mam nadzieję, że to pomoże.]}

Jason

 3
Author: Jason,
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
2011-04-08 17:47:27
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 */
 2
Author: justin,
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
2011-04-08 17:40:38

Czytanie od prawej do lewej ułatwia zrozumienie modyfikatorów.

Metoda const, która pobiera odniesienie do wskaźnika const do const int o nazwie Method3, która zwraca wskaźnik const do const int.

  1. metoda const nie może modyfikować członków (chyba, że są one explicite mutable)
  2. const nie może być zmieniono, aby wskazać na coś innego
  3. const int (lub jakikolwiek inny typ) nie może be modified
 1
Author: Nick Strupat,
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
2011-04-08 17:40:37

Const # 1: Wskaźnik zwracany przez Method3 odnosi się do const int.

Const # 2: wartością wskaźnika zwracaną przez samą funkcję jest const. Jest to bezużyteczny const (choć poprawny gramatycznie), ponieważ wartość zwracana z funkcji nie może być wartością l.

Const #3: typ wskaźnika przekazany przez odniesienie do funkcji wskazuje na const int.

Const # 4: wartość wskaźnika przekazywana przez odniesienie do funkcji jest sama w sobie wskaźnikiem const. Deklarowanie wartości to jest przekazywane do funkcji jako const normalnie byłoby bezcelowe, ale ta wartość jest przekazywana przez odniesienie, Więc może być znaczące.

Const #5: Funkcja (prawdopodobnie funkcja członkowska) jest const, co oznacza, że nie wolno (a) przypisywać nowych wartości do żadnych członków obiektu, którego jest częścią lub (b) wywoływać funkcji non-const na obiekcie lub którymkolwiek z jego członków.

 1
Author: Jollymorphic,
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
2011-04-08 17:41:12

Łatwy sposób na zapamiętanie const w C++ jest wtedy, gdy widzisz jakiś kod w postaci:

XXX const;
const YYY;

XXX, YYY będzie stałym składnikiem,
XXX const forma:

function ( def var ) const;    ------#1
* const;                       ------#2

const YYY forma:

const int;                     ------#3
const double;
Ludzie zwykle używają tych typów. Kiedy widzisz "const&" gdzieś, nie czuj się zdezorientowany, const opisuje coś przed sobą. tak więc odpowiedź na ten problem jest teraz oczywista.
const int* const Method3(const int* const&) const;
  |          |             |          |       |
  #3         #2            #3         #2      #1
 1
Author: Albert Chen,
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
2014-11-29 23:28:06

Chcę tylko wspomnieć, że {[1] } jest rzeczywiście stałym odniesieniem do const int*. Na przykład:

int i = 0;
int j = 1;
int* p = &i;
int* q = &j;
const int* const& cpref = p;
cpref = q; //Error: assignment of read-only reference 'cpref'

Jest to również przypadek int* const&, co oznacza: "stałe odniesienie do int*".
Ale const int*& jest niezmiennym odniesieniem do const int*.
Mam nadzieję, że to pomoże.

 1
Author: MrDetective,
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
2015-02-16 20:50:24
  • const Na końcu metody znajduje się kwalifikator oznaczający, że stan obiektu nie będzie zmieniany.

  • const int*const& oznacza otrzymanie przez odniesienie wskaźnika const do lokalizacji const. Nie może zmienić się, aby wskazać inne miejsce, ani zmienić wartość, na którą wskazuje.

  • const int*const jest wartością zwracaną, która jest również stałym wskaźnikiem do stałej lokalizacji.

 0
Author: Mahesh,
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
2011-04-08 17:40:41

Kilka przykładów może być miło zademonstrować tę koncepcję, im więcej tym lepiej imho.

class TestClass
{
private:
   int iValue;
   int* oValuePtr;
   int& oValueRef;

public:
   int TestClass::ByValMethod1(int Value)
   {
      // Value can be modified
      Value++;

      // iValue can be modified
      iValue = Value;
      iValue += 1;

      // Return value can be modified
      return ++iValue;
   }

   int TestClass::ByValMethod2(const int Value)
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // iValue can be modified
      iValue = Value;
      iValue += 1;

      // Return value can be modified
      return ++iValue;
   }

   const int TestClass::ByValMethod3(int Value)
   {
      // Value can be modified
      Value++;

      // iValue can be modified
      iValue = Value;
      iValue += 1;

      // Return value can be modified
      return ++iValue;
   }

   const int TestClass::ByValMethod4(const int Value)
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // iValue can be modified
      iValue = Value;
      iValue += 1;

      // Return value can be modified
      return ++iValue;
   }

   const int TestClass::ByValMethod5(const int Value) const
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // iValue *cannot* be modified
      // Access through a const object
      iValue = Value;
      iValue += 1;

      // Return value *cannot* be modified
      // Access through a const object
      return ++iValue;
   }

   int& TestClass::ByRefMethod1(int& Value)
   {
      // Value can be modified
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   int& TestClass::ByRefMethod2(const int& Value)
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   const int& TestClass::ByRefMethod3(int& Value)
   {
      // Value can be modified
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   const int& TestClass::ByRefMethod4(const int& Value)
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   const int& TestClass::ByRefMethod5(const int& Value) const
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   int* TestClass::PointerMethod1(int* Value)
   {
      // Value can be modified
      Value++;

      // oValuePtr can be assigned
      oValuePtr = Value;

      // oValuePtr can be modified
      oValuePtr += 1;

      // Return value can be modified
      return ++oValuePtr;
   }

   int* TestClass::PointerMethod2(const int* Value)
   {
      // Value can be modified
      Value++;

      // oValuePtr cannot be assigned
      // const int* to int*
      oValuePtr = Value;

      // oValuePtr can be modified
      oValuePtr += 1;

      // Return value can be modified
      return ++oValuePtr;
   }

   const int* TestClass::PointerMethod3(int* Value)
   {
      // Value can be modified
      Value++;

      // oValuePtr can be assigned
      oValuePtr = Value;

      // iValue can be modified
      oValuePtr += 1;

      // Return value can be modified
      return ++oValuePtr;
   }

   const int* TestClass::PointerMethod4(const int* Value)
   {
      // Value cannot be modified
      Value++;

      // oValuePtr *cannot* be assigned
      // const int* to int*
      oValuePtr = Value;

      // oValuePtr can be modified
      oValuePtr += 1;

      // Return value can be modified
      return ++oValuePtr;
   }

   const int* TestClass::PointerMethod5(const int* 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 modified
      return ++oValuePtr;
   }
};
Mam nadzieję, że to pomoże!
 0
Author: Rastus7,
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
2014-11-24 02:10:42