답변:
이것을 읽으십시오 : 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
라는 멤버 함수 로 읽을 수 있습니다 .Method3
const
int const
const int
const
int const
const int
(Nb # 2 는 완전히 불필요 합니다.)
우선은 const T
동일합니다 T const
.
const int* const
따라서는 int const * const
.
const
토큰과 포인터 가 많은 표현식을 읽을 때는 항상 오른쪽에서 왼쪽 으로 읽으십시오 (위의 변환을 적용한 후). 따라서이 경우 반환 값은 constint
에 대한 const 포인터 입니다. const
반환 값이 수정할 수있는 lvalue가 아니기 때문에 포인터 자체를 만드는 것은 의미가 없습니다. const
그러나 pointee를 만들면 호출자가에서 반환 한 int
(또는의 배열)을 수정할 수 없습니다 .int
Method3
const int*const&
해진다 int const*const&
그것이 그래서, CONST에 CONST 포인터 참조int
. 참조에 의해 const 포인터를 전달하는 것도 의미가 없습니다. 포인터가 const
있고 참조와 포인터가 동일한 저장소를 차지하므로 공간 절약도 없기 때문에 참조 값을 수정할 수 없습니다 .
마지막 const
은 메서드가 this
개체를 수정하지 않음을 나타냅니다 . this
메소드 본문 내에서 포인터는 (이론적) 선언을해야합니다 T const * const this
. 이것은 const T*
객체가를 호출 할 수 있음을 의미합니다 T::Method3()
.
const
으로는 문구의 머리 부분에 첫 번째 s를 넣지 않으면 모든 것이 더 합리적이라는 점을 지적하기 위해 이것 (및 ildjarn의 유사한 답변)에 투표 하십시오. 이것이 const
언어가 허용하더라도 거기 에 넣는 것이 나쁜 습관이라고 생각하는 이유 이며 가장 일반적인 사용법입니다.
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 */
디코딩을 위해 식별자 이름 (이 경우 ) 에서 시작 하여 왼쪽에서 오른쪽에서 뒤에서 왼쪽으로 앞뒤로 읽는 "clock"또는 "spiral"방법 을 사용하고 싶습니다 Method3
. 명명 규칙. const int* const Method3(const int* const&) const
클래스 멤버 (이름이 지정되지 않은 클래스)를 변경하지 않고 상수를 가리키는 포인터에 대한 상수 참조를 가져와 상수에 대한 int
상수 포인터를 반환 하는 클래스 메서드도 마찬가지 입니다 int
.
도움이 되었기를 바랍니다,
제이슨
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* 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 int에 Method3
대한 const 포인터를 반환하는 호출 된 const int에 대한 const 포인터에 대한 참조를받는 const 메서드입니다 .
mutable
)const # 1 : Method3에서 반환 된 포인터는 const int를 참조합니다.
const # 2 : 함수 자체가 반환하는 포인터 값은 const입니다. 함수의 반환 값이 l- 값이 될 수 없기 때문에 이것은 쓸모없는 const입니다 (그래도 유효하지만).
const # 3 : 함수 참조로 전달 된 포인터 유형은 const int를 가리 킵니다.
const # 4 : 함수에 대한 참조로 전달되는 포인터 값은 그 자체로 const 포인터입니다. 함수에 전달되는 값을 const로 선언하는 것은 일반적으로 무의미하지만이 값은 참조로 전달되므로 의미가있을 수 있습니다.
const # 5 : 함수 (아마도 멤버 함수)가 const입니다. 즉, (a) 자신이 속한 개체의 멤버에 새 값을 할당하거나 (b) 상수가 아닌 멤버 함수를 호출 할 수 없습니다. 개체 또는 그 구성원 중 하나에.
이 개념을 보여주는 데 몇 가지 예가 좋을 수 있습니다.
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;
}
};
이게 도움이 되길 바란다!