일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 메타테이블
- 영화
- 영화 리뷰
- reference
- 게임
- 참조자
- operator new
- resource management class
- 다형성
- Vector
- 티스토리챌린지
- c++
- 암시적 변환
- 언리얼
- virtual function
- Smart Pointer
- Effective c++
- implicit conversion
- 루아
- 예외
- lua
- 스마트 포인터
- 비교 함수 객체
- 반복자
- UE4
- 오블완
- 상속
- exception
- more effective c++
- effective stl
Archives
- Today
- Total
스토리텔링 개발자
[Effective C++] 18. 인터페이스 설계 본문
728x90
항목 18. 인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 하자
제대로 쓰기엔 쉽고 엉터리로 쓰기엔 어려운 인터페이스 개발
- 사용자가 저지를만한 실수의 종류를 머리에 넣어두고 있어야 한다.
- 날짜를 나타내는 클래스의 생성자를 예로 들어보자.
-
Date(int month, int day, int year);
- 문제점
- 매개변수의 전달 순서가 잘못될 여지가 열려있다.
- 각 매개변수를 새로운 타입으로 하여 인터페이스를 강화할 수 있다.
- 월과 일에 해당하는 숫자가 어이없는 숫자일 수 있다.
- 각 매개변수에 해당하는 적절한 타입이 준비되어 있으면 각 타입값에 제약을 가할 수 있다.
- 매개변수의 전달 순서가 잘못될 여지가 열려있다.
인터페이스 개발을 위한 방편들
- 매개변수를 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
'개발 > Effective C++' 카테고리의 다른 글
[Effective C++] 20. const & 전달하기 (0) | 2024.06.13 |
---|---|
[Effective C++] 19. 클래스 설계 (0) | 2024.06.12 |
[Effective C++] 17. 스마트 포인터 생성 시 예외 문제 (0) | 2024.06.10 |
[Effective C++] 16. new, delete 짝 맞춤 문제 (0) | 2024.06.07 |
[Effective C++] 15. 자원 관리 클래스 get 함수 제공하기 (0) | 2024.06.05 |
Comments