56. const 정확성: const 멤버 함수·mutable·const 오버로딩·const_cast

난이도 중 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C++
// 주제: const 정확성 — const 멤버 함수, 논리적 const 와 mutable, const 오버로딩, const_cast
//
// 아래 프로그램의 출력을 예측하고, 각 줄이 나오는 이유를 C++ const 규칙으로 설명하라.
// 특히 다음을 논하라:
//   - const 객체/참조에서 어떤 오버로드(const vs 비-const 멤버 함수)가 선택되는가.
//   - mutable 멤버가 const 멤버 함수 안에서 왜 수정 가능한가(논리적 const).
//   - const_cast 로 const 를 벗겨 수정하는 것이 언제 합법이고 언제 UB 인가.
//
// 과제:
//  1) 표준 출력을 한 줄씩 예측하라.
//  2) name() 두 오버로드 중 각 호출에서 무엇이 선택되는지 설명하라.
//  3) 이 코드의 const_cast 가 UB 가 아닌 이유와, UB 가 되는 변형 예를 제시하라.
//  g++ -std=c++17 로 컴파일/실행된다.

#include <iostream>
#include <string>

struct Widget {
    int value = 10;
    mutable int accessCount = 0;
    std::string name_ = "orig";

    int get() const { ++accessCount; return value; }

    const std::string& name() const { std::cout << "const\n"; return name_; }
    std::string&       name()       { std::cout << "non-const\n"; return name_; }
};

int main() {
    Widget w;
    const Widget& cw = w;

    std::cout << w.get() << "\n";
    std::cout << cw.get() << "\n";
    std::cout << w.accessCount << "\n";

    w.name() = "changed";
    const std::string& n = cw.name();
    std::cout << n << "\n";

    const_cast<Widget&>(cw).value = 99;
    std::cout << w.value << "\n";
    return 0;
}
내 리뷰 · C++
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.