const는 객체가 수정되지 않음을 보장한다.

포인터와 포인터가 가리키는 데이터

const char *p = hello; // 데이터만 const
char * const p = hello; // 포인터만 const
const char * const p = hello // 데이터, 포인터 모두 const

STL iterator

std::vector<int> vec{1, 2, 3};
//이터레이터 자체 수정 불가
const std::vector<int>::iterator iter = vec.begin()
*iter = 10; // 데이터는 수정 가능
++iter;     // 오류 (iter가 const)

// 이터레이터가 가리키는 데이터 수정 불가
std::vector<int>::const_iterator cIter = vec.begin()
*cIter = 10; // 오류 (데이터 수정 불가)
++cIter;     // iterator 수정 가능

함수에서 const

(1) 함수 반환값

const Rational operator*(const Rational& lhs, const Rational& rhs);

// 반환값이 const가 아닌 경우 의도치 않은 오류가 발생할 수 있음
(a * b) = c;
if((a * b) == c) 를 의도 했지만 = 을 빼먹어서 오류 발생함
const로 operator* 반환값을 선언하면 오타로 인한 오류 차단

(2) const 멤버 함수와 오버로딩

class TextBlock {
public:
    const char& operator[](std::size_t position) const {
        return text[position];
    }
    
    char& operator[](std::size_t position) {
        return text[position];
    }
    
private:
    std::string text;
};

const TextBlock ctb("World");
std::cout << ctb[0];    // const 버전의 operator[] 호출     
ctb[0] = 'x'            // const 객체이므로 오류

TextBlock tb("Hello");
std::cout << tb[0]; // non-const 버전의 operator[] 호출
tb[0] = 'H';        // non-const 객체는 수정 가능

(3) 논리적 const 구현

class TEST 
{
	public:
		std::size_t length() const { // const 멤버 함수
        if (!lengthValid) { 
            textLength = std::strlen(pText); // 길이 계산 후 저장
            lengthValid = true; // 캐싱 상태 업데이트
        }
        return textLength;
    }
    private:
	    const char* pText;
	    mutable std::size_t extLength
	    mutable bool lengthValid;
}