[Effective C++] 19. 클래스 설계는 타입 설계와 똑같이 취급하자
728x90
반응형
새로운 클래스를 정의한다는 것은 새로운 타입을 하나 정의하는 것과 같다.
효과적인 클래스 설계를 위한 질문들
1. 새로 정의한 타입의 객체 생성 및 소멸은 어떻게 이루어져야 하는가?
- 이 부분에 따라 클래스의 생성자와 소멸자의 설계가 바뀐다.
- 메모리 할당 함수(operator new, operator new [], operator delete, operator delete [])를 직접 작성할 경우 설계에 영향을 미친다.
2. 객체 초기화는 객체 대입과 어떻게 달라야 하는가?
- 생성자와 대입 연산자의 동작 및 둘 사이의 차이점을 결정짓는다.
- 초기화와 대입은 각각에 해당되는 함수 호출이 다르므로 헷갈리지 않는 것이 가장 중요하다.
3. 새로운 타입으로 만든 객체가 값에 의해 전달되는 경우에 어떤 의미를 줄 것인가?
- 값에 의한 전달을 구현하는 쪽은 복사 생성자라는 걸 기억하자.
4. 새로운 타입이 가질 수 있는 적법한 값에 대한 제약은 무엇으로 잡을 것인가?
- 클래스 데이터 멤버의 몇 가지 조합 값만은 반드시 유효해야 한다.
이런 조합을 불변 속성이라고 하며 클래스 차원에서 지켜주어야 함. - 불변 속성에 따라 클래스 멤버 함수 안에서 해주어야 할 에러 점검 루틴이 결정된다.
- 특히 생성자, 대입 연산자, setter함수는 불변 속성에 많이 좌우된다.
- 불변 속성은 함수가 발생시키는 예외에도 영향을 미치며, 예외 지정을 쓸 경우 그 부분에도 영향을 미침
5. 기존의 클래스 상속 계통망에 맞출 것인가?
- 이미 존재하는 클래스를 상속받아 설계 시 이들 클래스에 의해 제약을 받음
- 멤버 함수의 가상, 비가상 여부가 가장 큰 요인이다.
- 내가 만든 클래스를 다른 클래스에 상속받을 수 있게 하려 한다면, 이에 따라 가상 함수 여부가 결정되며 특히 소멸자가 그렇다.
6. 어떤 종류의 타입 변환을 허용할 것인가?
- 타입 변환이 되도록 하고 싶다면 암시적/명시적 타입 변환을 선택해서 만들어야 한다. (항목 15 참고)
7. 어떤 연산자와 함수를 두어야 의미가 있을까?
- 어떤 것들이 멤버 함수로 적당할 것이고, 또 몇몇은 그렇지 않을 것이다. (항목 23, 24, 26 참고)
8. 표준 함수들 중 어떤 것을 허용하지 말 것인가?
- 어떤 함수를 private로 선언해야 하는지 생각하자.
9. 새로운 타입의 멤버에 대한 접근권한을 어느 쪽에 줄 것인가?
- 클래스 멤버에 대한 public, protected, private 영역을 결정하자.
- friend로 만들어야 할 클래스 및 함수와 클래스 안에 다른 클래스를 중첩시켜도 될지도 생각하자.
10. 선언되지 않은 인터페이스로 무엇을 둘 것인가?
- 만들 타입이 제공할 보장이 어떤 종류인가에 대한 질문이다.
- 보장할 수 있는 부분은 수행성능 및 예외 안정성(항목 29 참고), 자원 사용(잠금 및 동적 메모리)이다.
- 보장하겠다고 결정한 결과는 클래스 구현에 있어서 제약으로 작용한다.
11. 새로 만드는 타입이 얼마나 일반적인가?
- 새로 만드는 것은 하나의 타입이 아니라 동일 계열의 타입 군일 수 있다.
- 그렇다면 새로운 클래스를 만드는 것이 아니라 새로운 클래스 템플릿을 정의해야 한다.
12. 정말로 꼭 필요한 타입인가?
- 기존의 클래스에서 기능 몇 개가 아쉽다면, 파생 클래스를 만들지 않고 비멤버 함수나 템플릿을 몇 개 더 정의하는 편이 낫다.
요약
- 클래스 설계는 타입 설계이다. 새로운 타입을 정의하기 전에, 이번 항목에 나온 모든 고려사항을 점검해보자.
728x90
반응형
'Books > Effective C++' 카테고리의 다른 글
[Effective C++] 21. 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자 (0) | 2022.06.03 |
---|---|
[Effective C++] 20. 값에 의한 전달보다는 상수객체 참조자에 의한 전달 방식을 택하는 편이 대개 낫다 (0) | 2022.05.29 |
[Effective C++] 18. 인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 하자 (0) | 2022.05.29 |
[Effective C++] 17. new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자 (0) | 2022.05.28 |
[Effective C++] 16. new 및 delete를 사용할 때는 형태를 반드시 맞추자 (0) | 2022.05.25 |
댓글
이 글 공유하기
다른 글
-
[Effective C++] 21. 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자
[Effective C++] 21. 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자
2022.06.03 -
[Effective C++] 20. 값에 의한 전달보다는 상수객체 참조자에 의한 전달 방식을 택하는 편이 대개 낫다
[Effective C++] 20. 값에 의한 전달보다는 상수객체 참조자에 의한 전달 방식을 택하는 편이 대개 낫다
2022.05.29 -
[Effective C++] 18. 인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 하자
[Effective C++] 18. 인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 하자
2022.05.29 -
[Effective C++] 17. new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자
[Effective C++] 17. new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자
2022.05.28