jessi68 / effiective-c-

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

항목 28: 내부에서 사용하는 객체에 대한 핸들을 반환하는 코드는 피하자

jessi68 opened this issue · comments

struct RectData {
  Point ulhc;
 Point lrhc;
}

class Rectangle {
  public:
// 사용자 정의 타입을 전달할 때는 값에 의한 전달보ㄷ다는 참조에 의한 전달방식을 쓰는 것이 더 효율적이다. 
   Point & upperrLeft() const {returrn pData->ulhc;}
  Point & lowerRight() const {return pData->lrhc;} 
  private:
   std::tr1::shared_ptr<RectData> pData;
}

이 코드는 문제점이 있는데, 그것은 바로 upperLeft 를 호출한 쪽은 rec 의 private 한 곳에 숨겨진 Point
데이터 멤버를 참조자로 끌어와 바꿀 수 있는데 rec 은 상수 객체로 선언되어있기 때문에 모순된다.

**교훈: 클래스 데이터 멤버는 아무리 숨겨봤자 그 멤버의 참조자를 반환하는 함수들의 최대 접근도에 따라 캡슐화 정도가 정해진다
. **

위 문제의 해결책은 간단한데

 const Point & upperrLeft() const {returrn pData->ulhc;}
  const Point & lowerRight() const {return pData->lrhc;} 

이렇게 반환타입에 const 를 붙여주면 사용자는 사각형을 정의하는 두 꼭짓점 값을 읽을 수는 있지만
값을 바꿀수 없습니다. 호출부에서 객체의 상태를 바꾸지 못하도록 컴파일러 수준에서 막아준다.

핸들을 반환하는 멤버함수를 웬만하면 두지 말라.
다만 필요한 상황도 있는데, 예를 들어 operator[] 연산자는 string 이나 vector 등의
클래스에서 개개의 원소를 참조할 수 있게 만드는 용도로 제공되고 있는데,
실제로 이 연산자는 내부적ㅇ으로 해당 컨테이너에 들어있는 개개의 원소 데이터에 대한
참조자를 반환하는 식으로 동작합니다.
이 원소데이터는 컨테이너가 사라질 때 같이 사라지는 데이터ㅓ입니다.