상세 컨텐츠

본문 제목

항목 19) 클래스 설계는 타입 설계와 똑같이 취급하자

C++/Effective C++

by DeaKyungLee 2021. 12. 5. 18:14

본문

좋은 클래스 설계를 위해서 신경써야하는 부분들에 대해서 정리

  • 새로 정의한 타입의 객체 생성 및 소멸은 어떻게 진행할 것인가?
    → 이 부분을 통해서 클래스의 생성자 및 소멸자의 설계가 변경된다.
    또한 메모리 할당 함수(new, delete) 를 직접 작성할 경우에는 이들 함수의 설계에도 영향을 준다.
  • 객체 초기화는 객체 대입과 어떻게 달라야 할 것인가?
    → 생성자와 대입 연산자의 동작 및 둘 사이의 차이점을 결정짓는 요소이다.
  • 새로운 타입으로 만들 객체가 값에 의해 전달되는 경우에 어떤 의미를 둘 것 인가?
    → 어떤 타입에 대해서 값에 의한 전달을 구현하는 쪽은 복사 생성자인데, 해당 부분에 대한 설계를 어떻게 했느냐는 의미이다.
  • 새로운 타입이 가질 수 있는 적법한 값에 대한 제약은 무엇으로 잡을 것인가?
    → 특정 클래스의 데이터 멤버는 몇 가지 값 조합에만 유효하거나, 반대로 특정 값에 대해서는 유효하지 않을 수 있다.
    이러한 특징을 클래스의 불변속성 ( invariant ) 이라고 하는데, 클래스 차원에서 일관성 있게 지켜주어야 한다.
    class Rational
    {
    public:
        Rational(int n = 0, int d = 1);
        ~Rational();
     
    public:
        void setDenominator(int d)    
        {
            d == 0 ? error_msg("zero divide"): denominator = d;
        }
     
     
    private:
        int numerator, denominator;
    };​
  • 예를 들어서 위의 코드에서 denominator 멤버 변수는 결코 0이 될 수 없으며, 그것이 클래스 설계자의 의도이다.
    생성자, 대입 연산자, 각종 Write 관련 함수 ( setter ) 는 불변속성에 많이 좌우되는 편이다. ( + 예외 처리 관련 )
  • 기존의 클래스 상속 계통망에 맞출 것인가?
    → 이미 있는 클래스로부터 상속시킨다고 하면, 당연히 해당 부모 클래스에 의해 제약을 받게 된다.
    특히나 멤버 함수의 가상, 비가상 여부는 가장 큰 요인이다.
    반대로 해당 클래스를 다른 클래스의 상속 시킬 목적으로 (즉, 부모 클래스로서 만든다면 ) 설계한다면 어떤 함수를 가상화 할지도 중요한 결정 요인이 된다.
  • 어떤 종류의 타입 변환을 허용할 것 인가?
    → 다른 타입과의 변환을 허용할 건 인가에 대한 고민도 필요하다.
    만약 암시적(implicitly) 변환을 허용한다면 operator T2 와 같은 함수를 따로 준비하던가, 비명시 호출 생성자를 T2의 멤버로 만들어야 한다.
    만약 명시적(explicit) 타입 변환만 허용하고 싶다면, 해당 변환을 맡는 별도 이름의 함수를 만들되 타입 변환 연산자 ( 인자 하나로 호출되는 ) 혹은 비명시호출 생성자는 만들지 말아야 한다.
  • 어떤 연산자와 함수를 두어야 의미가 있을까?
    → 클래스 멤버 함수의 목적이 여기서 결정된다.
  • 새로운 타입의 멤버에 대한 접근 권한을 어느 쪽에 줄 것인가?
    → 어떤 클래스 멤버를 public, protected, private 영역에 둘 것인가를 결정하는 질문이다.
    또한 프렌드 함수 및 클래스, 중첩 클래스에 대한 결정에도 영향을 준다.
  • 선언되지 않은 인터페이스로 무엇을 둘 것인가?
    → 새로 만들 타입이 제공할 보장이 어떤 종류인지에 대한 질문이다.
    보장하겠다고 선택할 수 있는 후보는 수행 성능 및 예외 안전성, 자원 사용이 있다.
    이것들에 대해서 보장을 하겠다는 결정을 하면 거기에 맞는 제약이 같이 결정된다.
  • 새로 만들 타입이 얼마나 일반적인가?
    → 단순히 다른 클래스 하나가 아니라 동일 계열의 타입군 전체를 정의해야 하는 상황이라면,
    새로운 클래스가 아닌 새로운 클래스 템플릿을 정의해야 한다.
  • 정말로 필요한 타입인가?
    → 단순히 비멤버 함수를 새롭게 정의하거나, 템플릿을 몇 개 더 정의해서 해결된다면 새 클래스를 정의하는 것은 낭비이다.

 

Things to Remember

  • 클래스 설계는 타입 설계와 마찬가지이다. 새로운 타입을 정의하기 전에, 위의 고려 사항들을 고민해보자.

관련글 더보기

댓글 영역