IT story

C ++ 상수 사용법 설명

hot-time 2020. 8. 31. 08:25
반응형

C ++ 상수 사용법 설명


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

누군가 각 const의 사용법을 설명 할 수 있습니까?


이것을 읽으십시오 : https://isocpp.org/wiki/faq/const-correctness

마지막 const은 함수 Method3가 클래스의 변경 불가능한 멤버를 수정하지 않음을 의미합니다 .

const int* const일정한 수단 INT에 일정한 포인터 : 즉 포인터를 변경할 수없는 int로 변경 될 수있다 : 이것과의 유일한 차이점 const int&이있을 수 있다는null

const int* const&상수 int에 대한 상수 포인터에 대한 참조를 의미합니다. 일반적으로 포인터는 참조로 전달되지 않습니다. const int* &메서드 호출 중에 포인터가 변경 될 수 있다는 것을 의미하기 때문에 더 의미가 있습니다. 참조로 포인터를 전달할 수있는 유일한 이유 const int* const&는 모든 의도와 목적에 대한 const int* const것입니다. 포인터는 POD (Plain Old Data) 유형이며 일반적으로 값으로 전달되어야합니다.


완전히 동등한 것으로 다시 작성하면 이해하기 더 쉽습니다.

// 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;

그런 다음 오른쪽에서 왼쪽으로 읽으십시오.

# 5는 왼쪽에있는 전체 함수 선언이라고 말하는데 const, 이는 이것이 반드시 자유 함수가 아닌 멤버 함수임을 의미합니다.

# 4는 왼쪽의 포인터가 const(다른 주소를 가리 키도록 변경할 수 없음) 이라고 말합니다 .

# 3은 int왼쪽이 const(다른 값을 갖도록 변경할 수 없음) 이라고 말합니다 .

# 2는 왼쪽 포인터가 const입니다.

# 1은 int왼쪽이 const입니다.

모두 합치면, 에 대한 포인터 (또는 원하는 경우)에 대한 참조를 취하고 ( )에 대한 포인터를 반환하는 const이름 멤버 함수 로 읽을 수 있습니다 .Method3constint constconst intconstint constconst int

(Nb # 2 는 완전히 불필요 합니다.)


우선은 const T동일합니다 T const.

const int* const따라서는 int const * const.

const토큰과 포인터 가 많은 표현식을 읽을 때는 항상 오른쪽에서 왼쪽 으로 읽으십시오 (위의 변환을 적용한 후). 따라서이 경우 반환 값은 constint 에 대한 const 포인터 입니다. const반환 값이 수정할 수있는 lvalue가 아니기 때문에 포인터 자체를 만드는 것은 의미가 없습니다. const그러나 pointee를 만들면 호출자가에서 반환 한 int(또는의 배열)을 수정할 수 없습니다 .intMethod3

const int*const&해진다 int const*const&그것이 그래서, CONST에 CONST 포인터 참조int . 참조로 const 포인터를 전달하는 것도 의미가 없습니다. 포인터가 const있고 참조 및 포인터가 동일한 저장소를 차지하므로 공간 절약도 없기 ​​때문에 참조 된 값을 수정할 수 없습니다 .

마지막 const은 메서드가 this개체를 수정하지 않음을 나타냅니다 . this메소드 본문 내에서 포인터는 (이론적) 선언을해야합니다 T const * const this. 이것은 const T*객체가를 호출 할 수 있음을 의미합니다 T::Method3().


의 규칙을 기억하는 쉬운 방법 const은 다음과 같이 생각 const하는 것입니다. 왼쪽에 아무것도 없으면 왼쪽에있는 것에 적용됩니다.

따라서의 경우 const int * const첫 번째 const는 왼쪽에 아무것도 없으므로 적용되고 int번째 const에는 왼쪽에 무언가가 있으므로 포인터에 적용됩니다.

이 규칙은 또한 const int const *. int이 표현식 대한 두 const 적용 은 중복되므로 유효하지 않습니다.


디코딩을 위해 식별자 이름 (이 경우 ) 에서 시작 하여 왼쪽에서 오른쪽에서 뒤에서 왼쪽으로 앞뒤로 읽는 "clock"또는 "spiral"방법 을 사용하고 싶습니다 Method3. 명명 규칙. const int* const Method3(const int* const&) const클래스 멤버 (이름이 지정되지 않은 클래스)를 변경하지 않고 상수를 가리키는 포인터에 대한 상수 참조를 가져와 상수에 대한 int상수 포인터를 반환 하는 클래스 메서드도 마찬가지 입니다 int.

도움이 되었기를 바랍니다,

제이슨


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 */

C ++에서 const를 기억하는 쉬운 방법은 다음과 같은 형식의 코드를 볼 때입니다.

XXX const;
const YYY;

XXX, YYY는 다음
XXX const형식 의 상수 구성 요소입니다 .

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

const YYY 형태:

const int;                     ------#3
const double;

사람들은 일반적으로 이러한 유형을 사용합니다. "const&"어딘가 를 볼 때 혼란스러워하지 마십시오. const는 자신보다 먼저 무언가를 설명합니다. 그래서이 문제의 답은 자명합니다.

const int* const Method3(const int* const&) const;
  |          |             |          |       |
  #3         #2            #3         #2      #1

오른쪽에서 왼쪽으로 읽으면 수정자를 더 쉽게 이해할 수 있습니다.

const int에 Method3대한 const 포인터를 반환하는 호출 const int에 대한 const 포인터에 대한 참조를받는 const 메서드입니다 .

  1. const 메서드는 멤버를 수정할 수 없습니다 (빠른 경우가 아니면 mutable)
  2. const 포인터는 다른 것을 가리 키도록 변경할 수 없습니다.
  3. const int (또는 다른 유형)는 수정할 수 없습니다.

const # 1 : Method3에서 반환 된 포인터는 const int를 참조합니다.

const # 2 : 함수 자체가 반환하는 포인터 값은 const입니다. 함수의 반환 값이 l- 값이 될 수 없기 때문에 이것은 쓸모없는 const입니다 (그래도 유효하지만).

const # 3 : 함수 참조로 전달 된 포인터 유형은 const int를 가리 킵니다.

const # 4 : 함수에 대한 참조로 전달되는 포인터 값은 그 자체로 const 포인터입니다. 함수에 전달되는 값을 const로 선언하는 것은 일반적으로 무의미하지만이 값은 참조로 전달되므로 의미가있을 수 있습니다.

const # 5 : 함수 (아마도 멤버 함수)가 const입니다. 즉, (a) 자신이 속한 개체의 멤버에 새 값을 할당하거나 (b) 상수가 아닌 멤버 함수를 호출 할 수 없습니다. 개체 또는 그 구성원 중 하나에.


나는 그것이 const int* const&실제로 const int*. 예를 들면 :

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'

의 경우이기도합니다. int* const&즉, ""에 대한 상수 참조 int*입니다.
그러나 const int*&에 일정하지 않은 참조입니다 const int*.
도움이 되었기를 바랍니다.


  • const 메서드의 끝에는 개체의 상태가 변경되지 않을 것임을 나타내는 한정자가 있습니다.

  • const int*const&const 위치에 대한 const 포인터를 참조로 수신하는 것을 의미합니다. 다른 위치를 가리 키도록 변경하거나 가리키는 값을 변경할 수 없습니다.

  • const int*const 상수 위치에 대한 상수 포인터이기도 한 반환 값입니다.


이 개념을 보여주는 데 몇 가지 예가 좋을 수 있습니다.

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;
   }
};

이게 도움이 되길 바란다!

참고URL : https://stackoverflow.com/questions/5598703/c-const-usage-explanation

반응형