mutable 키워드
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 30번째.
const 멤버 함수는 어떤 멤버 변수도 수정할 수 없다는 것을 배웠습니다. 하지만 때로는 객체의 논리적 상태에 영향을 주지 않는 멤버를 변경해야 할 때가 있습니다. 예를 들어 캐시나 access 카운터가 이에 해당합니다. mutable 키워드는 const 제한에 대한 예외를 제공합니다.
mutable 멤버는 const 멤버 함수 내부에서도 수정할 수 있습니다:
class DataFetcher {
std::string data;
mutable int accessCount; // const 함수에서 수정될 수 있음
public:
DataFetcher(std::string d) : data(d), accessCount(0) {}
std::string getData() const {
accessCount++; // accessCount가 mutable이기 때문에 허용됨
return data;
}
int getAccessCount() const {
return accessCount;
}
};mutable이 없으면, const 함수 getData() 내부에서 accessCount를 증가시키는 것은 컴파일러 오류를 발생시킵니다. mutable 키워드는 컴파일러에 다음과 같이 알려 줍니다. "객체가 const로 간주되는 경우에도 이 멤버는 변경할 수 있습니다."
mutable의 일반적인 사용 사례로는 계산된 값의 캐싱, 액세스 통계 추적, 뮤텍스와 같은 동기화 기본 요소가 있습니다. 각각의 경우 수정은 객체가 논리적으로 나타내는 것을 변경하지 않습니다. 캐시된 값은 단지 최적화일 뿐이며, 액세스 카운터는 사용량에 대한 메타데이터입니다.
class Circle {
double radius;
mutable double cachedArea;
mutable bool areaCached;
public:
double getArea() const {
if (!areaCached) {
cachedArea = 3.14159 * radius * radius;
areaCached = true;
}
return cachedArea;
}
};mutable은 아껴서 사용하세요. 객체의 관찰 가능한 상태에 영향을 주지 않는 멤버에만 적용해야 합니다.
챌린지
쉬움읽기 전용 메서드의 const 정확성을 깨뜨리지 않고 문서가 조회된 횟수를 추적하는 문서 뷰어를 만들어 봅시다. 이는 mutable 키워드에 아주 적합한 사용 사례입니다.
코드를 구성하기 위해 두 개의 파일을 만듭니다:
Document.h: 콘텐츠를 저장하고 조회 통계를 비밀리에 추적하는Document클래스를 정의합니다. 클래스에는 다음이 필요합니다:- private 멤버:
title(문자열),content(문자열), 그리고 const 메서드에서도 수정할 수 있는mutable int viewCount - title과 content를 매개변수로 받고
viewCount를0으로 초기화하는 생성자 - title을 반환하는
getTitle()const 메서드 viewCount를 증가시키고(mutable이므로 허용됨) content를 반환하는getContent()const 메서드- content에 액세스된 횟수를 반환하는
getViewCount()const 메서드 - content의 처음 20개 문자를 반환한 뒤
"..."을 추가하는getPreview()const 메서드. 단순한 미리 보기이므로 조회 수를 증가시키면 안 됩니다
- private 멤버:
main.cpp: 메서드를 논리적으로 const로 유지하면서 mutable을 통해 액세스 통계를 추적하는 방법을 보여 줍니다. 입력에서 문서 title과 content를 읽습니다(각각 별도의 줄). 그런 다음:- 입력 값으로
Document를 생성합니다 "Title: <title>"을 출력합니다"Preview: <preview>"를 출력합니다"Views after preview: <count>"를 출력합니다getContent()를 사용하여 전체 content에 액세스하고"Content: <content>"를 출력합니다"Views after first read: <count>"를 출력합니다- content에 다시 액세스하고
"Content: <content>"를 출력합니다 "Views after second read: <count>"를 출력합니다"[Const Access] <title>: <content>"를 출력하는 도우미 함수void displayDocument(const Document& doc)를 생성합니다. 이는 const 참조에서도 const 메서드가 작동한다는 것을 보여 줍니다- 문서와 함께
displayDocument()를 호출합니다 "Final view count: <count>"를 출력합니다
- 입력 값으로
미리 보기는 전체 조회로 간주되지 않으므로 미리 보기 후 조회 수는 0이어야 하며, 이후 getContent()가 호출될 때마다 증가해야 합니다. mutable 키워드가 이를 가능하게 합니다. mutable이 없다면 getContent()와 같은 const 메서드 내부에서 viewCount를 수정할 수 없습니다.
content가 20자보다 짧다면 getPreview()는 전체 content를 반환한 뒤 "..."을 추가해야 합니다.
직접 해보기
#include <iostream>
#include <string>
#include "Document.h"
using namespace std;
// TODO: displayDocument 함수를 구현하세요
// 다음과 같이 출력해야 합니다: "[Const Access] <title>: <content>"
void displayDocument(const Document& doc) {
// TODO: 이 함수를 구현하세요
}
int main() {
// 입력 읽기
string title;
string content;
getline(cin, title);
getline(cin, content);
// TODO: 입력 값으로 Document를 생성하세요
// TODO: "Title: <title>"을 출력하세요
// TODO: "Preview: <preview>"를 출력하세요
// TODO: Print "Views after preview: <count>"
// TODO: 전체 콘텐츠에 접근하고 "Content: <content>"를 출력하세요
// TODO: Print "Views after first read: <count>"
// TODO: 콘텐츠에 다시 접근하고 "Content: <content>"를 출력하세요
// TODO: Print "Views after second read: <count>"
// TODO: document와 함께 displayDocument()를 호출하세요
// TODO: Print "Final view count: <count>"
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 C++ 컴파일러