C++ 끄적임
[ C++ ] Mutable
algohun
2024. 12. 2. 16:12
C++에서 mutable은 다소 생소한 키워드입니다.
mutable은 const 함수에서 특정 멤버 변수의 값을 변경할 수 있도록 허용합니다.
이번 글에서는 mutable의 동작과 필요성, 그리고 관련된 실험 결과를 다룹니다.
1. mutable 키워드란?
mutable은 const 함수에서 값 변경이 필요한 변수 앞에 사용하는 키워드입니다. 이를 통해 객체의 논리적 불변성을 유지하면서도 부수적인 상태 변경이 가능해집니다.
mutable의 사용 예시
다음은 로그 기록을 위한 간단한 예제입니다.
#include <iostream>
using namespace std;
class Data {
public:
Data() :logCount{}{}
void PrintLog() const{
++logCount;
cout << "[" << logCount << "]\n";
}
private:
mutable int logCount;
};
int main()
{
Data d;
for (int i = 0; i < 10; ++i) {
d.PrintLog();
}
}
- PrintLog는 const 함수로 선언되어 있습니다. 따라서 일반적인 멤버 변수는 수정이 불가능합니다.
- 그러나, logCount는 mutable 키워드로 선언되어 있어 const 제한을 무시하고 수정할 수 있습니다.
2. 왜 mutable이 필요할까?
mutable의 필요성
mutable 키워드는 다음과 같은 상황에서 사용됩니다:
- 로그 기록: 로그 횟수 카운트 등 부수적인 상태 변경.
- 캐싱: 연산 결과를 저장하여 반복 계산 방지.
- 참조 횟수 관리: 스마트 포인터 등에서 사용.
이러한 작업들은 객체의 논리적 불변성(Logical Constness)에는 영향을 미치지 않지만, 물리적 상태(Physical State)를 변경해야 할 필요가 있습니다.
3. const 함수에서 값 변경이 제한되는 이유
const 함수에서 멤버 변수 수정이 제한되는 이유는 this 포인터의 동작에 있습니다.
this 포인터와 const
const 함수 내부에서는 this 포인터가 const ClassName* 타입으로 처리됩니다. 이는 다음을 의미합니다:
- this는 변경 불가능한(const) 객체를 가리킨다고 간주됩니다.
- 따라서, const 함수는 멤버 변수 값을 변경할 수 없습니다.
4. 실험: this의 타입 출력
this가 const로 처리된다는 것을 확인하기 위해 실험을 진행했습니다.
#include <iostream>
#include <type_traits>
#include <string>
class Example {
private:
int value;
mutable int mutableValue;
public:
Example(int val) : value{val},mutableValue{val} {}
void nonConstFunction() {
std::cout << "nonConstFunction this type: "
<< (std::is_const<std::remove_pointer<decltype(this)>::type>::value
? "const"
: "non-const")
<< std::endl;
}
void constFunction() const {
std::cout << "constFunction this type: "
<< (std::is_const<std::remove_pointer<decltype(this)>::type>::value
? "const"
: "non-const")
<< std::endl;
}
};
int main() {
Example ex(10);
ex.nonConstFunction();
ex.constFunction();
}
출력 결과
nonConstFunction this type: non-const
constFunction this type: const
분석
- nonConstFunction: this는 일반 객체를 가리키므로 non-const로 출력됩니다.
- constFunction: this는 변경 불가능한 객체를 가리키므로 const로 출력됩니다.
5. mutable 변수의 타입은?
다음으로, mutable 변수의 타입을 확인하는 실험을 진행했습니다.
void constFunction() const {
std::cout << "constFunction this type: "
<< (std::is_const<std::remove_pointer<decltype(mutableValue)>::type>::value
? "const"
: "non-const")
<< std::endl;
}
결과는 non-const가 출력됐습니다.
mutable 변수는 const 함수 내부에서도 변경 가능한 상태로 처리되므로, non-const로 출력되었습니다.
6. 결론
- mutable은 const 함수에서 특정 멤버 변수의 값을 변경 가능하게 만듭니다.
- const 함수에서 멤버 변수 수정이 제한되는 이유는, this 포인터가 const 객체를 가리키는 포인터로 처리되기 때문입니다.
- mutable은 로그 기록, 캐싱, 참조 횟수 관리 등 부수적 상태 변경이 필요한 상황에서 유용합니다.