티스토리 뷰
반응형
✅ 클래스에서 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;
}
};
🧠 구성 설명 요약
✅ 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 보장 없는 함수를 호출하려고 해서 막음"
🧠 요점 정리
반응형
✅ 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");
🧠 요점 정리
✅ 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가 붙어 있어도 호출에는 아무런 문제가 없다.
🧠 요점 정리
따라서 getter는 const로 선언하는 것이 설계상 유리합니다.
양쪽 모두 지원되고, 내부 상태 불변도 보장됩니다.
✅ 6. const 멤버 함수는 "불변성에 대한 약속"
🎯 목적
- const 멤버 함수는 단순한 문법이 아니라, “이 함수는 내부 상태를 바꾸지 않는다”는 약속
- const 객체에서 호출할 수 있는 유일한 함수 조건
📌 다시 예시 정리
int getId() const; // 내부 상태를 절대 바꾸지 않음
void setId(int newId); // 내부 상태 변경이 목적
📌 차이점 요약
🧠 설계 철학
- const 객체는 읽기 전용
- const 함수는 읽기 전용 함수 → 읽기 전용 객체에는 읽기 전용 함수만 허용
반응형
✅ 7. const 멤버 함수는 항상 붙이는 것이 좋다
🎯 결론
getter 함수는 기본적으로 const를 붙여야 합니다. 그 이유는 다음과 같습니다:
✔️ 이유 1. const 객체에서도 사용 가능
- const를 붙이지 않으면 const 객체에서는 호출 불가
- const를 붙이면 일반 + const 객체 둘 다 사용 가능
✔️ 이유 2. 함수의 의미 명확화
- 이 함수는 내부 상태를 건드리지 않는다 → 코드 문서화 효과
✔️ 이유 3. 실수 방지
- 함수 내에서 실수로 멤버 변수 변경 시, 컴파일러가 차단
📌 최종 요약
✅ 마무리 요약
- const 객체는 내부가 변경되지 않기를 요구
- const 함수는 내부를 변경하지 않겠다는 약속
- 둘이 일치할 때에만 함수 호출 가능
- 따라서 getter에는 항상 const를 붙이는 것이 바람직