수색…


통사론

  • 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 * 입니다. 즉, 함수 내에서 멤버 변수를 변경할 수 없습니다. 컴파일러가 경고를 내 보냅니다. 따라서 setMyIntconst 로 선언 될 수 없습니다.

가능한 경우 멤버 함수를 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'; 
}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow