설계 및 선언
항목18. (명언) "제대로 쓰기에는 쉽게, 엉터리로 쓰기에는 어렵게"
- 단순 매개변수, var의 저장/TOSS시에도 간단한 wrapper type (ex. year, month, day)
- "When in doubt, do as the ints do"
- (아예)스마트 포인터를 반환하여 실수 방지
- shared_ptr 은 auto_ptr와 돤리 삭제자를 엮을 수 있다
std::tr::shared_ptr<Inve> pInv(static_cast<Inve>(0), getRidOfInvestment);
*null 보다 '미리 할 수 있으면' 바로 pInv 생성자에 넘기는 것이 바람직.
→ (항목 26) "객체가 정말로 필요할 때까지 선언 대기!"
- 교차 DLL 문제 : A DLL → new, B DLL → delete시 런타임에러
→ shared_ptr 해결 (할당한 DLL 에서)
항목19. 클래스 설계시 유의점
- 마치 언어설계자의 Type 선언처럼 세심한 정성 要
- 생성.소멸자의 설계
- 초기화 vs 대입
- 복사생성자시 값에 의한 전달
- 값들의 유효성(범위)제한
- 상속을 받을경우, 할경우 모두 가상함수 신경 (특히 소멸자)
- 암시적 타입변환 or 비명시 호출 or 명시적 호출
- 접근권한
- 수행성능, 예외 안정성, 자원사용의 '보장'
- 클래스 Template 염두
- 꼭 필요한 타입인가 염두
항목20. 값에 의한 전달 < 상수 객체 참조자에 의한 전달
- 객체 내부의 수 많은 멤버가 재생성되는 비효율성 초래
- 상수 참조시 비효율 X, '상수'이므로 손실 걱정 X
- 파생클래스→기본클래스의 값에 의한 전달시 : "복사손실문제" - 파생의 특성 사라짐
* 참조자는 pointer를 써서 구현됨. → 레지스터에 구현됨
항목21. 참조자 반환은 절대로 피하자
- 참조자를 반환하기 위해서는 그 개체의 본체가 만들어져야 한다. (본체 = 스택(지역) or 힙(NEW))
- 지역변수는 return 시 소멸됨, → 의미X
- new(객체 생성자의 호출)의 객체는 delete할 사람이 없다.
* ex. operator* → w=x*y*z; 사이의 new 된 객체들의 소멸 불가
- 정적 객체의 참조자 반환 → (a*b) == (c*d) → True 고정
- 새로운 객체 반환의 정석 → inline const Rational ~ {
return Rational(~)
}
항목22. 데이터 멤버는 private 여야 한다. (protected가 아니다!)
- 메서드 또는 변수의 문법 일관성
- 접근 제어의 의무화 (세분화하여야 한다 : 단방향/양방향 - 게터, 세터)
- 캡슐화 (계산 함수의 실시간성) → 클래스 불변속성 유지
항목23. 멤버 함수 보다는 비멤버,비프렌드 함수를 사용하자
- "캡슐화의 Level : private 접근 권한의 메소드 수"로 정의된다
→ 멤버함수 : 접근 가능, (비멤버 & "비프렌드" == 전역 비프렌드) → 접근불가 (== 캡슐화)
- 캡슐화의 장점 : 패키징 유연도 높음 & 컴파일 의존도가 낮음
- 더욱 자연스러운 구현 : namespace 안에 위치 (편의함수 - 응용도가 높음)
* STL들의 구현도 비멤버,비프렌드 같은 namespace(std) & 다양한 헤더
- namespace 분할 가능 but, 클래싀 정의의 확장/수정 불가능
→ 확장성이 높아짐
항목24. 타입변환이 모든 매개변수에 대해 적용하려면 "비멤버"함수를 사용해야 한다.
- explicit를 붙이지 않는 규칙의 예외
- oneHalf * 2 는 oneHalf.operator*(2); cf ) 2 * oneHalf
- 비멤버 operator* 가 답이다 * 이게 가능함을 느껴보라
항목25-1. swap의 효율을 위한 응용/특수화 (swap이 중요한게 아니라 특수화에 대하여..)
- swap의 원리는 복사 생성자 및 대입 연산자
- PImpl → 객체의 경우 무의미한 비용이 들 수 있음 :: PImple : ptr(실제데이터)를 다루는 객체
Pointer to Implementation → pimpl 포인터만 맞바꾸는 '완전 템플릿 특수화'
Template<> void swap<Widget> ( -- ) { → std namespace 내
- private 접근 불가 (pimpl 데이터 교환 불가) → public swap 선언 후 포인터 swap
- 위에서 Widget이 Template 클래스일 경우, template<typename T> void swap<Widget<T>>( - ) {
→ 함수 Template에 대한 부분특수화 : 오버로딩 → 함수 Template에 대한 부분특수화 X
→ std namespace에는 class, method 추가 금지!
→ 현재 namepsace에 swap 선언으로 간단히 해결 (namespace가 다르므로 오버로딩 X) → 이름탐색 규칙에 의함
항목25-2. 클래스 템플릿 및 특수화에 대한 부연
- 특수화란 Template<typename T>에 대하여 지정된 형식이 나올 경우 내용을 특수하게 변경하는것
(함수 템플릿, 클래스 템플릿 모두 가능함) template<> 후 메소드/클래스 정의
cf, 비슷한 형태로 default template가 있음
template<typename T=int, int len=7> 과 같이 사용 후 Widget<> wg;
- 함수 템플릿 특수화는 '완전 특수화'만 가능하다. type 여러개시 전부 특수화 → overloading 해결
- 클래시 템플릿 특후화도 '본문'을 특수 구성한다는 것임 → 클래스 전체 재구성 필요
* 함수 선택시 순서 : 일반함수 → 기본함수템플릿 → 오버로딩 → 특수화 함수 템플릿
* 완전 특수화 → 부분특수화 클래스 선택됨
'Development > C|C++|C#' 카테고리의 다른 글
[C#]csv 파일 읽기, 데이터 내 쉼표(숫자)처리 (0) | 2017.01.13 |
---|---|
[C#]마우스 제어, 컨트롤(클릭, 위치 가져오기) (0) | 2017.01.12 |
[Effective C++]3. 자원 관리 (0) | 2016.10.19 |
[C++]JSON 데이터 트리(Tree)스키마 파싱 논문 구현 (0) | 2016.10.19 |
[Effective C++]2. 생성자, 소멸자 및 대입 연산자 (0) | 2016.10.16 |