C, C++/C++ 언어 / / 2024. 7. 26.

[C++] const 속성과 mutable 키워드

const 멤버 함수와 mutable 키워드

const 멤버 함수는 함수 내에서 const 변수뿐만 아니라, 일반 변수의 값도 바꿀 수 없도록 제한을 건 클래스 멤버 함수입니다.

그리고, const 멤버 함수 내에서는 멤버 변수의 수정을 막기 위해 일반 멤버 함수도 사용할 수 없습니다.

const 멤버 함수에 관한 내용은 여기에서 볼 수 있습니다.

 

[C++] const 포인터, const 멤버 함수 및 const 클래스

const 포인터변수를 상수로 바꾸기 위해선 두 가지가 필요합니다.첫 번째는 const 키워드를 변수명 앞에 붙입니다.두 번째는 변수를 선언 시 초기화해야 됩니다.const int a; // compile error !! 선언과 동

codingembers.tistory.com

 

하지만, 경우에 따라 멤버 변수의 값을 변경하는 것이 필요한 때가 있습니다.

그때 사용할 수 있는 키워드가 mutable입니다.

 

mutable 키워드는 클래스의 데이터 멤버에 적용할 수 있는 키워드입니다.

이때, 데이터 멤버는 비정적( non-static ), 비참조( non-reference )이어야 하며, const 멤버 변수가 아니어야 합니다.

 

이렇게 mutable이 붙은 멤버 변수는 const 멤버 함수 내에서 값을 변경할 수 있습니다.

 

다음 예제는 mutable 키워드의 사용법을 보여줍니다.

class StateObj
{
    int m_flags;
    mutable int m_accessCount;  // mutable 변수

public:
    int GetFlag() const
    {
        m_accessCount++;    	// 객체에 접근한 횟수를 기록
        
        return m_flags;
    }
};

위의 GetFlag 함수는 const 멤버 함수입니다.

그렇지만, mutable 키워드를 사용해서 m_accessCount 멤버 변수의 값을 변경할 수 있습니다.

 

예를 하나 더 들어보겠습니다.

이 예제는 100,000개의 원소를 가진 vector의 합을 구하고, 재사용을 위해 그 값을 mutable 변수에 저장합니다.

이렇게 저장된 값은 데이터가 변경되어 재계산이 필요할 때 갱신하게 됩니다.

#include <vector>
#define SIZE    100000

class ComputeObj
{
    mutable bool m_bModified;       // mutable
    mutable int m_nComputedValue;

    std::vector<int> m_Buffer;

public:

    ComputeObj() : m_Buffer(SIZE, 10){}

    int ComputeSum() const {    	// const 멤버 함수
        
        if ( !m_bModified)
            return m_nComputedValue;    // 저장된 값
        
        int sum = 0;
        for( int x : m_Buffer){
            sum += x;
        }

        m_bModified = false;
        m_nComputedValue = sum; 	// 계산값을 저장
        return sum;
    }

    void ChangeValue(int idx, int val){
        m_Buffer[idx] = val;    
        m_bModified = true;
    }
};

 

람다 표현식( lamda expression )과 mutable 키워드

mutable은 람다 표현식( lamda expression )에도 사용할 수 있습니다.

 

람다 표현식에 관한 내용은 여기에 정리해 두었습니다.

 

[C++] 람다 표현식( lamda expression )에 대한 설명

람다 표현식( lamda expression )이란줄여서 람다( lamda )라고도 하는 람다 표현식은 익명의 함수 객체를 정의하고 사용하기 위한 표기법입니다.이 표현식은 간결한 기능을 구현하는데 너무 많은 손이

codingembers.tistory.com

 

람다는 외부의 변수를 수용( capture )할 때, 값( call by value ) 또는 참조 ( call by reference )의 형식으로 캡처( capture )할 수 있습니다.

만약, 외부의 변수를 값으로 캡처하면, 외부의 변수는 const 속성을 띠는데,

필요한 경우 mutable 키워드를 사용하여 const 속성을 제거할 수 있습니다.

int main(){

    vector<int> vec = { 1, 2, 3, 4, 5 };

    int sum = 0;
    for_each( vec.begin(), vec.end(), [sum](int val) mutable {
        sum += val; // sum의 const 속성이 없어짐
        cout << sum;
    });
    
    return 0;
}

위의 예제에서, sum 변수를 값으로 capture 하면 const 속성을 갖게 됩니다.

하지만, 이 const 속성을 mutable 키워드를 사용하여 제거하였습니다.

그래서, sum의 값을 변경할 수 있습니다.

하지만, 변수 sum 값으로 캡처했기 때문에, 외부의 sum의 값은 변경되지 않습니다.

 

 

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유