[Effective C++] 항목 21 ~ 23
항목 21 : 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자.
- 함수 수준에서 새로운 객체를 만드는 방법
- 스택에 만드는 방법 : 참조자 반환 시 이미 소멸된 객체의 참조자가 반환된다.
- 생성자가 불리는 게 싫어서 참조자 반환을 했으나 객체가 생성됨.
- 힙에 만드는 방법 : 여전히 생성자가 한번 호출된다.
- delete를 짝지어주기 힘들어진다.(메무리 누수)
- 스택에 만드는 방법 : 참조자 반환 시 이미 소멸된 객체의 참조자가 반환된다.
- 함수 내에 정적 객체 정의
- 문제점 1) 스레드 안정성 문제
- 문제점 2) 함수 리턴값 비교 시 같은 정적 객체를 비교하므로 항상 같다. »+ ex) if((ab) == (cd)) -> operator* 내부에 정적 객체 선언이 되어있을 시.. 항상 true
- 새로운 객체를 반환해야 하는 함수의 정도는 새로운 객체를 반환하게 만드는 것이다.
- ex)
const Rational operator*(const Rational &lhs, const Rational& rhs) return Rational(lhs.n * rhs.n, lhs.d * rhs.d);
- 생성 / 소물 비용이 들어가지만 올바른 동작에 지불되는 작은 비용이다.
- 반환값에 대한 생성 / 소멸 동작이 안전히 제거될 수 있다.
- 반환값 최적화(return value optimization)(RVO) : 지역 스택 객체의 포인터 / 참조자 반환, 힙에 할당된 객체의 참조자 반환, 지역 정적 객체의 포인터 / 참조자 반환은 그런 객체가 두개 이상 필요해질 가능성이 있으면 절대로 하지 말자.
- ex)
항목 22 : 데이터 멤버가 선언될 곳은 private 영역임을 명심하자.
- public 데이터 멤버의 문제점
- 문법적 일관성(18) : 공개 인터페이스가 함수 뿐 -> 괄호 필요 유무에 대한 고민이 필요 없어진다.
- 데이터 멤버 접근성의 정교한 제어 : 읽기 / 쓰기 접근을 직접 구현 가능하다.
- 캡슐화(encopsulation) : 내부 구현을 바꿀 수 있고 사용자는 컴파일만 다시 하면 된다.
- 구현상의 융통성을 전부 누릴 수 있다.(클래스 불변속성 / 사전조건 & 사후조건 검증 / 스레딩 환경 동기화 등)
- 캡슐화는 현재의 구현을 나중에 바꾸기로 결정할 수 있는 권한
- 캡슐화 되지 않았다 = 바꿀 수 없다.
-
클래스에서 제거되면 깨질 수 있는 코드의 양에 반비례해서 그 데이터 멤버의 캡슐화 정도가 감소한다.(23)
- public : 망가지는 코드가 파악이 힘들 정도로 많다.
- protected : 파생 클래스에서 망가지는 코드가 파악이 힘들 정도로 많다.
- 둘 다 캡슐화 되지 않은 것과 같다.
- 캡슐화 관점에서 쓸모 있는 접근 수준 - private(캡슐화 제공), private가 아닌 나머지(캡슐화 없음)
- protected는 public보다 더 많이 보호받고 있는 게 절대 아니다.
항목 23 : 멤버 함수보다는 비멤버 비프렌드 함수와 가까워지자.
- 객체 지향 법칙 : 할 수 있는 만큼 데이터를 캡슐화하라.
-
캡슐화를 통해 이미 있는 코드를 바꾸더라도 제한된 사용자들밖에 영향을 주지 않는 융통성을 확보할 수 있다.
- 비멤버 비프렌드 함수는 어떤 클래스의 private 멤버 부분을 접근할 수 있는 함수의 갯수를 늘리지 않는다.
- 주의점 1) 해당 클래스 접근권한과 동일하므로 비프렌드(non-friend)함수에만 적용된다.
- 주의점 2) 함수는 어떤 클래스의 비멤버가 되어야 한다 != 그 함수는 다른 클래스의 멤버가 될 수 없다
- 주의점 1) 해당 클래스 접근권한과 동일하므로 비프렌드(non-friend)함수에만 적용된다.
- 비멤버 함수로 두되 네임스페이스 안에 둔다.
- 클래스와 달리 네임스페이스는 여러 개의 소스파일로 쪼개진다.
- 멤버도 프렌드도 아니기 때문에 사용자 수준 이상의 기능 제공이 불가하다.
- 실사용 구성요소에만 컴파일 의존성을 고려할 수 있게 헤더 파일을 분배
- 네임스페이스가 여러 소스파일로 쪼개지니 가능하다.
- 확장도 손쉬워진다 : 해당 네임스페이스에 비멤버 비프렌드 함수 추가