수색…
통사론
- const 유형 myVariable = 초기; // const 변수를 선언합니다. 변경할 수 없다.
- const 유형 & myReference = myVariable; // const 변수에 대한 참조를 선언합니다.
- const 타입 * myPointer = & myVariable; // 포인터를 const로 선언합니다. 포인터는 변경 될 수 있지만 기본 데이터 멤버는 포인터를 통해 변경할 수 없습니다.
- 유형 * const myPointer = & myVariable; // const 포인터를 선언합니다. 포인터는 다른 것을 가리 키도록 다시 할당 할 수 없지만 기본 데이터 멤버는 변경할 수 있습니다.
- const 타입 * const myPointer = & myVariable; // const에 대한 const 포인터를 선언합니다.
비고
로 표시된 변수 const
1로 변경 될 수 없다. const가 아닌 작업을 호출하려고하면 컴파일러 오류가 발생합니다.
1 : 음, const_cast
통해 변경할 수 있지만 거의 사용하지 않아야합니다.
Const 로컬 변수
선언과 사용법.
// a is const int, so it can't be changed
const int a = 15;
a = 12; // Error: can't assign new value to const variable
a += 1; // Error: can't assign new value to const variable
참조와 포인터의 바인딩
int &b = a; // Error: can't bind non-const reference to const variable
const int &c = a; // OK; c is a const reference
int *d = &a; // Error: can't bind pointer-to-non-const to const variable
const int *e = &a // OK; e is a pointer-to-const
int f = 0;
e = &f; // OK; e is a non-const pointer-to-const,
// which means that it can be rebound to new int* or const int*
*e = 1 // Error: e is a pointer-to-const which means that
// the value it points to can't be changed through dereferencing e
int *g = &f;
*g = 1; // OK; this value still can be changed through dereferencing
// a pointer-not-to-const
Const 포인터
int a = 0, b = 2;
const int* pA = &a; // pointer-to-const. `a` can't be changed through this
int* const pB = &a; // const pointer. `a` can be changed, but this pointer can't.
const int* const pC = &a; // const pointer-to-const.
//Error: Cannot assign to a const reference
*pA = b;
pA = &b;
*pB = b;
//Error: Cannot assign to const pointer
pB = &b;
//Error: Cannot assign to a const reference
*pC = b;
//Error: Cannot assign to const pointer
pC = &b;
Const 멤버 함수
클래스의 멤버 함수는 const
로 선언 할 수 있습니다.이 함수는 컴파일러와 향후 독자에게이 함수가 객체를 수정하지 않는다고 알려줍니다.
class MyClass
{
private:
int myInt_;
public:
int myInt() const { return myInt_; }
void setMyInt(int myInt) { myInt_ = myInt; }
};
const
멤버 함수 this
포인터는 사실상 const MyClass *
대신 const MyClass *
MyClass *
입니다. 즉, 함수 내에서 멤버 변수를 변경할 수 없습니다. 컴파일러가 경고를 내 보냅니다. 따라서 setMyInt
는 const
로 선언 될 수 없습니다.
가능한 경우 멤버 함수를 const
로 표시해야합니다. const MyClass
에서는 const
멤버 함수 만 호출 할 수 있습니다.
static
메소드는 const
로 선언 할 수 없습니다. 이는 정적 메서드가 클래스에 속하며 object에서 호출되지 않기 때문입니다. 따라서 객체의 내부 변수를 수정할 수 없습니다. 따라서 static
메소드를 const
로 선언하면 중복 될 수 있습니다.
const 및 non-const getter 메소드에서 코드 중복 방지.
C ++에서 const
한정자와 만 다른 메서드는 오버로드 될 수 있습니다. 때로는 일부 멤버에 대한 참조를 반환하는 두 버전의 getter가 필요할 수 있습니다.
Foo
클래스로 만들자. 동일한 연산을 수행하고 Bar
유형의 객체에 대한 참조를 반환하는 두 가지 메소드가있다.
class Foo
{
public:
Bar& GetBar(/* some arguments */)
{
/* some calculations */
return bar;
}
const Bar& GetBar(/* some arguments */) const
{
/* some calculations */
return bar;
}
// ...
};
그들 사이의 유일한 차이점은 하나의 메소드가 non-const이고 비 const 레퍼런스 (객체 수정에 사용 가능)를 반환하고 두 번째 메소드는 const이며 const 참조를 반환한다는 것입니다.
코드 중복을 피하기 위해 다른 메소드에서 하나의 메소드를 호출하려는 유혹이 있습니다. 그러나 const가 아닌 메소드는 const 메소드에서 호출 할 수 없습니다. const가 아닌 메소드에서 const 메소드를 호출 할 수 있습니다. const qualifier를 제거하기 위해 'const_cast'를 사용해야합니다.
해결책은 다음과 같습니다.
struct Foo
{
Bar& GetBar(/*arguments*/)
{
return const_cast<Bar&>(const_cast<const Foo*>(this)->GetBar(/*arguments*/));
}
const Bar& GetBar(/*arguments*/) const
{
/* some calculations */
return foo;
}
};
위의 코드에서, 우리의 CONST 버전 호출 GetBar
비 CONST에서 GetBar
CONST 유형이 캐스트 : const_cast<const Foo*>(this)
. const가 아닌 메소드에서 const 메소드를 호출하기 때문에 객체 자체가 비 const이므로 const를 캐스팅 할 수 있습니다.
다음의보다 완전한 예를 살펴보십시오.
#include <iostream>
class Student
{
public:
char& GetScore(bool midterm)
{
return const_cast<char&>(const_cast<const Student*>(this)->GetScore(midterm));
}
const char& GetScore(bool midterm) const
{
if (midterm)
{
return midtermScore;
}
else
{
return finalScore;
}
}
private:
char midtermScore;
char finalScore;
};
int main()
{
// non-const object
Student a;
// We can assign to the reference. Non-const version of GetScore is called
a.GetScore(true) = 'B';
a.GetScore(false) = 'A';
// const object
const Student b(a);
// We still can call GetScore method of const object,
// because we have overloaded const version of GetScore
std::cout << b.GetScore(true) << b.GetScore(false) << '\n';
}