정보 은닉
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 104개 중 36번째.
정보 은닉(Information hiding)은 단순히 접근 제어자를 사용하는 것 그 이상을 의미합니다. 이는 데이터뿐만 아니라 클래스가 내부적으로 어떻게 작동하는지에 대한 구현 세부 사항까지 숨기는 디자인 원칙입니다.
목표는 클래스 사용자가 알아야 할 내용만 노출하고 나머지는 모두 숨기는 것입니다. 이를 통해 클래스를 사용하는 코드에 영향을 주지 않고 내부 구현을 변경할 수 있습니다.
class Temperature {
double kelvin; // 내부 표현 - 숨겨진 세부 사항
public:
void setCelsius(double c) {
kelvin = c + 273.15; // 사용자에게 숨겨진 변환 과정
}
double getCelsius() const {
return kelvin - 273.15;
}
double getFahrenheit() const {
return (kelvin - 273.15) * 9.0/5.0 + 32;
}
};이 클래스의 사용자는 온도가 내부적으로 켈빈(Kelvin) 단위로 저장된다는 사실을 알지 못하며(또는 알 필요가 없으며), 나중에 이를 섭씨(Celsius) 단위로 저장하기로 결정하더라도 비공개 구현(private implementation)만 변경하면 되고 공개 인터페이스(public interface)는 그대로 유지됩니다.
인터페이스와 구현 사이의 이러한 분리는 여러 가지 이점을 제공합니다. 클래스 사용자들의 복잡성을 줄여주고, 내부 데이터의 실수로 인한 오용을 방지하며, 코드를 유지 관리하기 더 쉽게 만듭니다. 내부 세부 사항이 숨겨져 있으면, 클래스에 의존하는 기존 코드를 망가뜨리지 않고 자유롭게 최적화하거나 리팩터링할 수 있습니다.
챌린지
쉬움거리를 내부적으로는 미터 단위로 저장하면서 다양한 단위를 사용할 수 있는 깔끔한 인터페이스를 제공함으로써 정보 은닉을 보여주는 Distance 클래스를 만들어 봅시다. 이 클래스의 사용자는 거리가 내부적으로 어떻게 저장되는지 알 필요가 없으며(또는 신경 쓸 필요가 없으며), 자신에게 편리한 단위를 사용하여 작업하기만 하면 됩니다.
코드를 구성하기 위해 두 개의 파일을 생성합니다:
Distance.h: 내부 표현을 숨기면서 유연한 퍼블릭 인터페이스를 노출하는Distance클래스를 정의합니다. 내부적으로는 거리를 센티미터(double타입)로 저장하세요. 이것이 숨겨진 구현 세부 사항입니다. 퍼블릭 인터페이스는 사용자가 다음을 수행할 수 있도록 해야 합니다:setMeters(double m),setCentimeters(double cm), 또는setKilometers(double km)를 사용하여 거리 설정getMeters(),getCentimeters(), 또는getKilometers()를 사용하여 거리 가져오기 — 모두 const 메서드여야 함- 새로운
Distance객체를 반환하는add(const Distance& other)를 사용하여 두 거리를 더하기
거리를 0으로 초기화하는 기본 생성자를 포함하세요. 변환 로직은 메서드 내부에 숨겨져야 합니다. 사용자는 내부 저장 형식을 걱정하지 않고
setKilometers(5)및getMeters()를 호출하기만 하면 됩니다.main.cpp: 사용자가 내부 표현을 알지 못해도 클래스를 사용할 수 있음을 보여줍니다. 입력에서 두 개의 거리 값을 읽습니다: 첫 번째는 미터 단위, 두 번째는 킬로미터 단위입니다. 그런 다음:Distance객체를 생성하고 미터 값을 사용하여 설정합니다."In meters: <value> m"를 출력합니다."In centimeters: <value> cm"를 출력합니다."In kilometers: <value> km"를 출력합니다.- 두 번째
Distance객체를 생성하고 킬로미터 값을 사용하여 설정합니다. - 두 거리를 더하고 그 결과를 저장합니다.
"Combined in meters: <value> m"를 출력합니다.
정보 은닉의 장점은 나중에 사용자가 클래스와 상호 작용하는 방식을 바꾸지 않고도 내부 저장 단위를 센티미터에서 밀리미터(또는 다른 단위)로 변경할 수 있다는 것입니다. 구현이 바뀌더라도 퍼블릭 인터페이스는 안정적으로 유지됩니다.
<iomanip>의 std::fixed 및 std::setprecision(2)를 사용하여 모든 출력 값을 소수점 둘째 자리까지 형식화하세요. std::stod()를 사용하여 입력 문자열을 double로 변환하세요.
변환 참조: 1미터 = 100센티미터, 1킬로미터 = 1000미터.
치트 시트
정보 은닉은 클래스가 내부적으로 어떻게 작동하는지에 대한 구현 세부 사항을 숨기고, 사용자가 알아야 할 내용만 노출하는 설계 원칙입니다.
이를 통해 클래스를 사용하는 코드에 영향을 주지 않고 내부 구현을 변경할 수 있습니다:
class Temperature {
double kelvin; // 내부 표현 - 숨겨진 세부 사항
public:
void setCelsius(double c) {
kelvin = c + 273.15; // 사용자에게 숨겨진 변환 과정
}
double getCelsius() const {
return kelvin - 273.15;
}
double getFahrenheit() const {
return (kelvin - 273.15) * 9.0/5.0 + 32;
}
};사용자는 온도가 내부적으로 켈빈(Kelvin) 단위로 저장된다는 사실을 알지 못하며(알 필요도 없습니다). 나중에 저장 형식을 변경하더라도 비공개(private) 구현만 변경될 뿐, 공개(public) 인터페이스는 그대로 유지됩니다.
정보 은닉의 이점:
- 클래스 사용자의 복잡성을 줄여줍니다
- 내부 데이터의 실수에 의한 오용을 방지합니다
- 코드를 유지 관리하고 리팩토링하기 쉽게 만듭니다
- 기존 코드를 손상시키지 않고 최적화를 가능하게 합니다
직접 해보기
#include <iostream>
#include <string>
#include <iomanip>
#include "Distance.h"
using namespace std;
int main() {
// 입력 값 읽기
string metersInput, kmInput;
cin >> metersInput; // 미터 단위의 첫 번째 값
cin >> kmInput; // 킬로미터 단위의 두 번째 값
// std::stod()를 사용하여 문자열을 double로 변환
double metersValue = stod(metersInput);
double kmValue = stod(kmInput);
// 출력 형식 설정
cout << fixed << setprecision(2);
// TODO: 첫 번째 Distance 객체를 생성하고 미터 값을 사용하여 설정
// TODO: "In meters: <value> m" 출력
// TODO: "In centimeters: <value> cm" 출력
// TODO: "In kilometers: <value> km" 출력
// TODO: 두 번째 Distance 객체를 생성하고 킬로미터 값을 사용하여 설정
// TODO: add() 메서드를 사용하여 두 거리를 합산
// TODO: "Combined in meters: <value> m" 출력
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.