반응형
0. 요약
- 클래스 설계는 타입 설계와 같다
- 아래 내용들을 깊게 고민하고 질문하자
1. 클래스 설계는 새로운 타입을 정의한다고 생각하자
- 함수와 연산자를 오버로딩
- 메모리 할당 및 해제를 제어
- 객체 초기화 및 종료를 처리하는 작업 정의
2. 효과적인 클래스 설계를 위한 질문들
새로 정의한 타입의 객체 생성 및 소멸은 어떻게 이루어져야 하는가?
- 이 부분에 따라 클래스 생성자/소멸자의 설계가 바뀜
- 메모리 할당 함수를 직접 작성할 경우 설계에 영향을 미침
객체 초기화는 객체 대입과 어떻게 달라야 하는가?
- 생성자와 대입 연산자의 동작 및 둘 사이의 차이점을 결정
- 초기화와 대입을 헷갈리지 말자!
새로운 타입으로 만든 객체가 값에 의해 전달되는 경우에 어떤 의미를 줄 것인가?
- 값에 의한 전달을 구현하는 쪽은 복사 생성자라는 점을 기억하자
새로운 타입이 가질 수 있는 적법한 값에 대한 제약은 무엇으로 잡을 것인가?
- 클래스 데이터 멤버 몇 가지 조합은 반드시 유효해야함
- 이런 조합을 불변속성이라고 하며, 클래스 차원에서 지켜줘야함
- 불변 속성에 따라 멤버 함수 안에서 해야할 에러 점검 루틴 결정
- 불변 속성에 따라 생성자, 대입 연산자, setter 함수 결정
- 불변 속성은 함수가 발생시키는 예외에도 영향을 미침
기존의 클래스 상속 계통망에 맞출 것인가?
- 이미 존재하는 클래스를 상속받아 설계시 이들 클래스에 의해 제약을 받음
- 멤버 함수의 가상 여부가 가장 큰 요인
- 내가 만든 클래스를 다른 클래스에서 상속받을 수 있게 한다면, 가상 함수 여부 결정이 필요함
어떤 종류의 타입 변환을 허용할 것인가?
- 새로운 클래스와 다른 타입간의 변환의 정의가 있어야함
- 암시적으로 변환하길 원한다면, 타입 연산자 오버로딩 필요
- 아니면, non-explicit 생성자를 T2 클래스에 넣어야함
- 명싲거으로 변환하길 원한다면, 변환을 맡는 함수를 만들자
- 이때 타입 변환 연산자 또는 non-explicit 생성자를 만들지 말자
어떤 연산자와 함수를 두어야 의미가 있을까?
- 클래스 안에 선언할 함수가 여기서 결정
표준 함수들 중 어떤 것을 허용하지 말 것인가?
- private로 선언해야 하는 함수를 결정
새로운 타입의 멤버에 대한 접근권한을 어느 쪽에 줄 것인가?
- 클래스 멤버에 대한 public, protected, private 영역 결정
- friend로 만들어야할 클래스 및 함수를 결정
선언되지 않은 인터페이스로 무엇을 둘 것인가?
- 만들 타입이 제공할 보장이 어떤 종류인가에 대한 질문
- 보장할 수 있는 부분은 수행 성능 및 예외 안전성 그리고 자원 사용
- 보장하겠다고 결정한 결과는 클래스 구현에 있어 제약으로 작용
새로 만드는 타입이 얼마나 일반적인가?
- 새로 만드는 것은 하나의 타입이 아니라 동일 계열의 타입군일 수 있다.
- 그렇다면, 새로운 클래스를 만드는 것이 아니라, 새로운 클래스 템플릿을 정의해야 한다!
정말로 꼭 필요한 타입인가?
- 기존의 클래스에서 기능 몇 개가 아쉽다면, 상속 받지 마라
- 간단하게 비멤버 함수 또는 템플릿을 정의하자!
참고
- Effective C++
반응형
'C++ > Effective C++' 카테고리의 다른 글
[Effective C++] 20. 값에 의한 전달보다는 상수객체 참조자에 의한 전달 방식을 선택하는 편이 대개 낫다 (0) | 2021.03.15 |
---|---|
[Effective C++] 18. 인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 하자 (0) | 2021.03.15 |
[Effective C++] 17. new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자 (0) | 2021.03.15 |
[Effective C++] 16. new 및 delete를 사용할 때는 형태를 반드시 맞추자 (0) | 2021.03.15 |
[Effective C++] 15. 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자 (0) | 2021.03.15 |