티스토리 뷰

반응형

✅ 클래스에서 Const란? 1편

✅ 1. 클래스 설계

🎯 목적

  • const란 변경을 막는 키워드로서, coonst를 사용하면 클래스 내 변경불가
  • const가 있는 경우와 없는 경우를 나누어서 const의 역할 분석


✅ 클래스 코드

class Student {
private:
    int id;
    std::string name;

public:
    Student(int idValue, std::string nameValue) {
        id = idValue;
        name = nameValue;
    }

    int getId() {
        return id;
    }

    std::string getName() {
        return name;
    }

    void setId(int newId) {
        id = newId;
    }

    void setName(std::string newName) {
        name = newName;
    }
};

🧠 구성 설명 요약

구성 요소 설명
멤버 변수 id, name – private 접근, 캡슐화 원칙 준수
생성자 객체 생성 시 id, name 초기화
getter 함수 내부 값을 읽기 위한 함수, const 없음
setter 함수 내부 값을 변경하는 함수, const 없음




✅ 2. 일반 객체 – 모든 함수 호출 가능

int main() {
    Student a(1001, "Alice");

    std::cout << a.getId() << std::endl;
    std::cout << a.getName() << std::endl;

    a.setId(2002);
    a.setName("Bob");

    std::cout << a.getId() << std::endl;
    std::cout << a.getName() << std::endl;
}

🔍 설명

  • a는 일반 객체로 선언
  • 모든 getter, setter 호출 가능
  • 내부 상태를 읽고, 수정하고, 다시 확인하는 흐름

🖨 출력 결과

1001
Alice
2002
Bob



✅ 3. const 객체 – 모든 함수 호출 불가

int main() {
    const Student s(2001, "Charlie");

    std::cout << s.getId() << std::endl;
    std::cout << s.getName() << std::endl;

    s.setId(3003);
    s.setName("Daniel");
}

🔍 설명

  • s는 const 객체로 선언되어, 내부 상태를 변경할 수 없어야 함
  • 하지만 현재 getId, getName는 단순히 값을 불러오는 메소드임에도 const가 없기 때문에
    → 컴파일러는 이 함수들이 내부를 바꿀 수도 있다고 판단
  • 그래서 getter조차 호출 불가능

❌ 컴파일 오류 발생

error: passing ‘const Student’ as ‘this’ argument discards qualifiers
이 오류의 의미:
"const 객체인데 const 보장 없는 함수를 호출하려고 해서 막음"



🧠 요점 정리

항목 설명
객체 선언 const Student s(...)
const 함수 없음 getter조차 호출 불가
setter 호출 불가 내부 상태 변경 시도이므로 당연히 오류
출력 발생 여부 ❌ 전혀 없음 (컴파일 자체 실패)



반응형

 


✅ 4. getter 함수에 const 추가 – const 객체에서도 호출 가능하게 만들기

🎯 목적

  • getter 함수는 내부 상태를 단순히 읽기만 하므로, const 객체에서도 호출 가능해야 함
  • 이를 위해 getter 함수 선언 뒤에 const를 명시

📌 클래스 수정: getter 함수에 const 추가

class Student {
private:
    int id;
    std::string name;

public:
    Student(int idValue, std::string nameValue) {
        id = idValue;
        name = nameValue;
    }

    int getId() const {
        return id;
    }

    std::string getName() const {
        return name;
    }

    void setId(int newId) {
        id = newId;
    }

    void setName(std::string newName) {
        name = newName;
    }
};

📌 테스트 코드 (const 객체)

int main() {
    const Student s(2001, "Charlie");

    std::cout << s.getId() << std::endl;
    std::cout << s.getName() << std::endl;

    s.setId(3003);
    s.setName("Daniel");
}

🔍 설명

  • getId()getName()은 이제 const 함수 → 내부상태를 바꾸지 않기 때문에 const 객체에서 호출 가능
  • setId(), setName()은 여전히 내부 상태를 바꾸므로 호출 불가능

🖨 출력 결과 (성공한 부분만)

2001
Charlie

❌ 아래 두 줄은 여전히 컴파일 에러:

s.setId(3003);
s.setName("Daniel");



🧠 요점 정리

함수 호출 가능 여부 이유
getId() ✅ 가능 const 함수로 내부 변경 없음 보장
getName() ✅ 가능 동일
setId() ❌ 불가능 내부 상태 변경 → const 객체에서 차단
setName() ❌ 불가능 동일




✅ 5. 일반 객체에서도 const 멤버 함수는 호출 가능

🎯 목적

  • const 멤버 함수는 const 객체에서만 사용 가능한 게 아니다.
  • 일반 객체에서도 당연히 const 함수 호출 가능하다 → 범용성 있음

📌 테스트 코드 (일반 객체 + const 함수 호출)

int main() {
    Student s(1001, "Alice");

    std::cout << s.getId() << std::endl;
    std::cout << s.getName() << std::endl;

    s.setId(2002);
    s.setName("Bob");

    std::cout << s.getId() << std::endl;
    std::cout << s.getName() << std::endl;
}

🔍 설명

  • 일반 객체 s는 const 객체가 아님
  • 하지만 getId() const 와 같은 const 멤버 함수는 내부 상태를 바꾸지 않으므로 일반 객체에서도 제약 없이 호출 가능

🖨 출력 결과

1001
Alice
2002
Bob

→ const가 붙어 있어도 호출에는 아무런 문제가 없다.


🧠 요점 정리

함수 선언 방식 일반 객체에서 호출 가능 const 객체에서 호출 가능
int getId() ✅ 가능 ❌ 불가능
int getId() const ✅ 가능 ✅ 가능

따라서 getter는 const로 선언하는 것이 설계상 유리합니다.
양쪽 모두 지원되고, 내부 상태 불변도 보장됩니다.



✅ 6. const 멤버 함수는 "불변성에 대한 약속"

🎯 목적

  • const 멤버 함수는 단순한 문법이 아니라, “이 함수는 내부 상태를 바꾸지 않는다”는 약속
  • const 객체에서 호출할 수 있는 유일한 함수 조건

📌 다시 예시 정리

int getId() const;     // 내부 상태를 절대 바꾸지 않음
void setId(int newId); // 내부 상태 변경이 목적

📌 차이점 요약

함수 종류 내부 상태 변경 여부 const 객체에서 호출 가능 여부
const 함수 ❌ 없음 ✅ 가능
일반 함수 ✅ 있음 ❌ 불가능

🧠 설계 철학

  • const 객체는 읽기 전용
  • const 함수는 읽기 전용 함수 → 읽기 전용 객체에는 읽기 전용 함수만 허용



반응형

 


✅ 7. const 멤버 함수는 항상 붙이는 것이 좋다

🎯 결론

getter 함수는 기본적으로 const를 붙여야 합니다. 그 이유는 다음과 같습니다:

✔️ 이유 1. const 객체에서도 사용 가능

  • const를 붙이지 않으면 const 객체에서는 호출 불가
  • const를 붙이면 일반 + const 객체 둘 다 사용 가능

✔️ 이유 2. 함수의 의미 명확화

  • 이 함수는 내부 상태를 건드리지 않는다 → 코드 문서화 효과

✔️ 이유 3. 실수 방지

  • 함수 내에서 실수로 멤버 변수 변경 시, 컴파일러가 차단



📌 최종 요약

상황 const 필요 여부 설명
읽기만 하는 함수(getter) ✅ 필요 const 객체 지원 + 의미 명확
값을 바꾸는 함수(setter) ❌ 불가 내부 변경 목적
일반 객체에서 const 함수 호출 ✅ 가능 아무 제약 없음
const 객체에서 일반 함수 호출 ❌ 불가능 내부 변경 가능성 존재




✅ 마무리 요약

  • const 객체는 내부가 변경되지 않기를 요구
  • const 함수는 내부를 변경하지 않겠다는 약속
  • 둘이 일치할 때에만 함수 호출 가능
  • 따라서 getter에는 항상 const를 붙이는 것이 바람직



반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함