Access Control

접근 지정자는 숨김 표시가 아니라 변경 권한의 경계다

public, private, protected는 문법 키워드보다 설계 약속에 가깝다. 어디서 상태를 바꿀 수 있는지를 좁힐수록 객체의 조건을 설명하기 쉬워진다.

01

외부 언어 선택

사용자가 알아야 하는 동작 이름만 public으로 남기고 자료구조 이름은 숨긴다.

02

변경 통로 축소

값 검증이 필요한 멤버는 setter보다 의미 있는 명령으로 바꾸는 편이 안전하다.

03

상속 경계 재검토

protected 멤버는 파생 클래스 전체에 내부 표현을 노출하므로 장기 결합을 만든다.

public 함수
계약 문서 반환값, 예외, 상태 변경 여부가 외부 코드의 의존점이 된다.
한 번 넓히면 줄이기 어렵다.
private 데이터
교체 가능한 표현 vector에서 deque로 바꿔도 호출부가 깨지지 않아야 한다.
테스트도 public 행동으로 검증한다.
protected
확장 포인트 파생 클래스가 지켜야 할 규칙을 문서화하지 않으면 private보다 위험하다.
가상 함수로 좁게 열 수 있는지 본다.
friend
제한된 특권 연산자나 직렬화처럼 객체 내부를 함께 읽어야 할 때만 사용한다.
전역 우회로로 쓰면 캡슐화가 사라진다.

상태 변경 · 파생 클래스 · 테스트 압박 점검

상태 변경 객체 내부 값을 바꾸는 함수가 검증 없이 public으로 열려 있지 않은가.
파생 클래스 protected 데이터에 직접 접근해야 한다면 상속 대신 위임이 더 단순하지 않은가.
테스트 압박 private를 테스트하려고 friend를 추가했다면 public 행동이 불명확하다는 신호일 수 있다.

좁은 공개면

class Account {
public:
    void deposit(int amount);
    bool withdraw(int amount);
    int balance() const;
private:
    int cents_ = 0;
};