diff --git a/EffectiveC++/Item19.md b/EffectiveC++/Item19.md new file mode 100644 index 0000000..40da0d3 --- /dev/null +++ b/EffectiveC++/Item19.md @@ -0,0 +1,61 @@ +## Item 19: 클래스 설계는 타입 설계와 똑같이 취급하자 + +객체 지향 프로그래밍 언어의 특징은 새로운 타입을 하나 정의할 수 있다는 점이다. (클래스로) 이는 언어 관점으로 봐도 막강한 권력이며 C++의 특성상 여기에 메모리 할당/해제의 개념까지 묶여있다. 이러한 영역에서 객체의 함수(오버로딩, 오버라이딩) 다형성의 개념과 생명주기까지 전부 관리해야 하니 신중하게 설계해야 한다. + +좋은 클래스를 설계하기란 어렵고 한번에 이뤄지는 것이 아니다. 좋은 타입이란 문법이 자연스럽고, 의미구조가 직관적이며 효율적인 구현이 한 가지 이상 가능해야 하는데, C++에서는 충분한 고민 없이 클래스 정의를 했다가는 이 세 가지 중 어느 것도 달성하기 힘들 수 있다. + +효과적인 클래스 설계를 위한 문답이 있으니 클래스를 설계하기 전 해당 문답에 답해보면 좋을 것 같다. + +### 새로 정의한 타입의 객체 생성 및 소멸은 어떻게 이루어져야 하는가? + +이 부분이 어떻게 되느냐에 따라 클래스 생성자 및 소멸자의 설계가 바뀐다. 그뿐 아니라 메모리 할당 함수(operator new, operator new[], operator delete, operator delete[])를 직접 작성할 경우 함수의 설계에도 영향을 미친다. + +### 객체 초기화는 객체 대입과 어떻게 달라야 하는가? + +생성자와 대입 연산자의 동작 및 둘 사이의 차이점을 결정 짓는 요소다. 초기화와 대입을 헷갈리지 않는 것이 가장 중요하다. 각각 해당되는 함수 호출이 아예 다르기 때문이다. + +### 새로운 타입으로 만든 객체가 값에 의해 전달되는 경우에 어떤 의미를 줄 것인가? + +**어떤 타입에 대해 '값에 의한 전달'을 구현하는 쪽은 바로 복사 생성자이다.** + +### 새로운 타입이 가질 수 있는 적법한 값에 대한 제약은 무엇으로 잡을 것인가? + +전부는 아니지만, 클래스의 데이터 멤버의 몇 가지 조합 값만은 반드시 유효해야 한다. 이런 조합을 가리켜 클래스의 불변속성이라고 하며, 클래스 차원에서 지켜주어야 하는 부분이다. 이 불변속성에 따라 클래스 멤버 함수 안에서 해 주어야 할 에러 점검 루틴이 좌우되는데, 특히 생성자, 대입 연산자, 각종 쓰기 함수는 불변속성에 의해 많이 좌우된다. + +### 기존의 클래스 상속 계통망에 맞출 것인가? + +이미 갖고 있는 클래스로부터 상속을 시킨다고 하면, 당연히 설계는 이들 클래스에 의해 제약을 받게 된다. 특히 멤버 함수가 가상인가 비가상인가의 여부가 가장 큰 요인이다. 직접 만든 클래스를 다른 클래스들이 상속할 수 있게 만들자고 결정했다면, 이에 따라 **멤버 함수의 가상 함수 여부**가 결정된다. + +### 어떤 종류의 타입 변환을 허용할 것인가? + +직접 만든 타입은 결국 기존의 수많은 타입들이 어울려야 하는 운명을 짊어진다. 타입과 다른 타입 사이에 변환 수단이 있어야 할지 여부를 결정해야 한다. 이는 클래스 설계에 큰 영향을 미친다. + +### 어떤 연산자와 함수를 두어야 의미가 있을까? + +클래스 안에 선언할 함수가 여기서 결정된다. + +### 표준 함수들 중 어떤 것을 허용하지 말 것인가? + +private로 선언해야 하는 함수가 여기에 해당된다. + +### 새로운 타입의 멤버에 대한 접근권한을 어느 쪽에 줄 것인가? + +어떤 클래스 멤버를 public, protected, private로 선언할지 결정하는 것이다. 이는 클래스 설계에 큰 영향을 미친다. + +### '선언되지 않은 인터페이스'로 무엇을 둘 것인가? + +직접 만들 탕비이 제공할 보장이 어떤 종류일지 고민해야 한다. 보장할 수 있는 부분은 수행 성능 및 예외 안전성 그리고 자원 사용이다. 이들에 대해 보장하겠다고 결정한 결과는 클래스 구현에 있어서 제약으로 작용하게 된다. + +### 새로 만드는 타입이 얼마나 일반적인가? + +실상은 타입 하나를 정의하는 것이 아닐지도 모른다. 직접 정의하는 것이 동일 계열의 타입군 전체일지도 모른다. 어쩌면 템플릿을 정의해야 할 것이다. + +### 정말로 꼭 필요한 타입인가? + +기존의 클래스에 대해 기능 몇 개가 아쉬워서 파생 클래스를 새로 뽑고 있다면, 차라리 간단하게 비멤버 함수라든지 템플릿을 몇 개 더 정의하는 편이 낫다. + +### 정리 + +어느하나 빼 먹을 수 없는 질문이면서 그만큼 효과적인 클래스를 정의하는 것이 무척이나 어렵다는 말이다. 하지만 이러한 설계에 대한 진지한 고민을 함으로써 가치있는 타입을 만들어 낼 수 있다. + +- 클래스 설계는 타입 설계다. 새로운 타입을 정의하기 전에, 이번 항목에 나온 모든 고려사항을 빠짐없이 점검해 보자.