스토리텔링 개발자

[Effective C++] 18. 인터페이스 설계 본문

개발/Effective C++

[Effective C++] 18. 인터페이스 설계

김디트 2024. 6. 11. 12:30
728x90

항목 18. 인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 하자

 

 

 

제대로 쓰기엔 쉽고 엉터리로 쓰기엔 어려운 인터페이스 개발
  • 사용자가 저지를만한 실수의 종류를 머리에 넣어두고 있어야 한다.
  • 날짜를 나타내는 클래스의 생성자를 예로 들어보자.
  • Date(int month, int day, int year);
  • 문제점
    1. 매개변수의 전달 순서가 잘못될 여지가 열려있다.
      • 각 매개변수를 새로운 타입으로 하여 인터페이스를 강화할 수 있다.
    2. 월과 일에 해당하는 숫자가 어이없는 숫자일 수 있다.
      • 각 매개변수에 해당하는 적절한 타입이 준비되어 있으면 각 타입값에 제약을 가할 수 있다.

 

 

 

인터페이스 개발을 위한 방편들
  • 매개변수를 enum으로 정의
    • 좋은 방법이지만, 때로는 int처럼 쓰일 수 있는 등, 타입 안정성이 그리 믿음직하지 못하다.
    • 타입 안정성이 신경쓰인다면 유효한 Month의 집합을 미리 정의해 두어도 좋을 것이다.
    • class Month
      {
      public:
          static Month Jan() { return Month(1); }
          static Month Feb() { return Month(2); }
          ...
      private:
      	explicit Month(int m); // Month 값이 새로 생성되지 않도록
                                 // 명시호출 생성자를 private 멤버로 처리
      };
      
      Date d(Month::Jan(), Day(30), Year(1995));

  • 매개변수에 const 붙이기
    • 어떤 타입이 제약을 부여하여 그 타입을 통해 할 수 있는 일들을 묶어버리자.
    • if (a * b = c) ...
      // operator *의 리턴값에 const를 붙임으로써
      // 비교하려고 했다가 발생한 오타를 컴파일 단에서 잡을 수 있게 된다.
  • 그렇게 하지 않을 번듯한 이유가 없다면 사용자 정의 타입은 기본 제공 타입처럼 동작하게 만들 것.
    • 일관성 있는 인터페이스를 제공하자.
  • 사용자 쪽에서 뭔가를 외워야 쓸 수 있는 인터페이스는 잘못 쓰기 쉽다.
    • Investment* createInvestment();
      // 이 함수의 반환값은 마지막에 delete로 정리해줘야 함을 기억해야 한다.
    • 해결법 : 스마트포인터를 반환하게 만든다. 
    • std::shared_ptr<investment> createInvestment();

 

 

 

shared_ptr 할당 이슈
  • shared_ptr은 사용자 정의 삭제자를 지원한다.
  • 헌데 아직 실 객체를 생성하지 않은 시점에서 사용자 정의 삭제자를 반영한 스마트 포인터를 만들고 싶다면 어떻게 해야 할까.
  • 0을 가리킬 객체로 캐스트하며 만들면 된다.
    • std::shared_ptr<Investment> pInv(static_cast<Investment*>(0), getRidOfInvestment);
  • 스마트 포인터를 생성하는 시점보다 먼저 관리할 실제 객체의 포인터를 결정할 수 있다면, 스마트 포인터를 널로 초기화하고 나서 나중에 대입하는 것보다 더 낫다.
  • shared_ptr는 포인터별 삭제자를 자동으로 씀으로써 교차 DLL 문제를 방지할 수 있다.
    • shared_ptr 기본 삭제자는 실 객체를 생성한 DLL과 동일한 DLL에서 delete를 사용하도록 만들어져 있기 때문이다.

 

 

 

교차 DLL 문제
  • 객체 생성 시 어떤 동적 링크 라이브러리(DLL)의 new를 썼는데 그 객체를 삭제할 때는 이전의 DLL과 다른 DLL에 있는 delete를 사용하는 경우.
  • new / delete 짝이 실행되는 DLL이 달라서 꼬이게 되면 대다수의 플랫폼에서 런타임 에러가 발생한다.

 

728x90
Comments