Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Effective C++ Chaper 1

2,176 views

Published on

Effective C++ 챕터 1 정리 슬라이드 입니다.
개인적인 해석이 많이 들어가 있다는점 고려해주세요

Published in: Engineering
  • Be the first to comment

Effective C++ Chaper 1

  1. 1. EFFECTIVE C++ 정리 Chapter 1
  2. 2. 짬뽕 언어 C++ ITEM 1
  3. 3. Item 1: 짬뽕언어 C++ • 다중 패러다임 프로그래밍 언어 • 절차적 (procedure), • 객체지향 (object-oriented), • 함수형 (functional), • 일반화 (generic), • 메타프로그래밍 (meta-programming)
  4. 4. Item 1: 짬뽕언어 C++ • 다중 패러다임 프로그래밍 언어 • 절차적 (procedure)  C언어 기반으로 제작 • 객체지향 (object-oriented)  클래스를 쓰는 C • 함수형 (functional)  람다 • 일반화 (generic)  템플릿, STL • 메타프로그래밍 (meta-programming)  TMP
  5. 5. Item 1: 짬뽕언어 C++ • 여러 하위 언어들의 연합 (FEDERATION) • Divide And Conquer • 단 하나의 정답은 없다.
  6. 6. #define 쓰기 전에 잠깐만.. ITEM 2
  7. 7. Item 2 : #define 쓰기 전에 잠깐만.. • #define 정의의 문제점 • #define ASPECT_RATIO 1.653 //OUT • 전처리기에 의해 단순 전치되는 값. • 컴파일 기호 테이블에 들어가지 않는다. • 컴파일 디버그에서 의미파악 불분명 • 사용할 때마다 사본 생성 (ex: 긴 문자열의 경우)
  8. 8. Item 2 : #define 쓰기 전에 잠깐만.. • 일반 상수 변수를 사용하자 • const double AspectRatio = 1.653; • 컴파일러가 인식하는 기호 • 사본 생성 X • const char* const authorName = “Scott Meyers”; • 상수 포인터는 내용 상수성 체크 • 문자열 상수는 왠만하면 std::string 씁시다.
  9. 9. Item 2 : #define 쓰기 전에 잠깐만.. • 클래스 멤버 상수면 static 쓰자. • 상수의 scope를 클래스로 제한할 때 • 헤더에만 쓰면 정의 아니고 선언 • 주소가 필요한 경우 cpp에 정의 필요 • const int GamePlayer::NumTurns; • 상수 초기화는 선언에 하는 것이 옳다 class GamePlayer { ... private: static const int NumTurns = 5; ... };
  10. 10. Item 2 : #define 쓰기 전에 잠깐만.. • 정적 멤버 상수 못쓰는 경우 • 컴파일러 구린건 정적 멤버 선언 시 초기화 못함. • 초기값을 상수 정의 시점에 주면 된다. • 클래스 컴파일 시점에 클래스 전용 상수가 필요하다면? • Enum Hack! (나열자 둔갑술…이름 구림) • enum { NumTurns = 5}; • 마치 scope가 있는 #define마냥 사용할 수 있다. • TMP에서 자주 사용되는 기법.
  11. 11. Item 2 : #define 쓰기 전에 잠깐만.. • 눈물이 나려고 하는 #define 매크로 함수 • #define MAX(a, b) f((a) >(b)) ? (a) : (b) • 인자로 뭐가 들어갈지 알 수가 없다. • inline 템플릿 함수로 바꿔 쓰자. • inline으로 매크로의 효율을 유지하면서 안전하게 사용가능 int a = 5, b = 0; MAX(++a, b); //a == 7 MAX(++a, b + 10); //a == 6 template<typename T> inline void max(const T& a, const T& b) { return (a > b) ? a : b; }
  12. 12. 일단 const 쓰고 생각한다. ITEM 3
  13. 13. Item 3: 일단 const를 쓰고 생각한다. • const의 멋짐을 모르는 당신은 너무 불쌍해 • 의미적 제약을 소스 코드 수준에서 붙일 수 있음 • const == “외부 변경 불가능” • 이 제약을 컴파일러에서 처리함. • 빠른 오류 검출 • 전역 상수 정의 할 때도 사용됨 (item 2)
  14. 14. Item 3: 일단 const를 쓰고 생각한다. • 복잡한(것 처럼 보이는) 규칙 • const(데이터의 상수성) char * const (포인터의 상수성) • STL iterator의 상수성 • 반복자는 T *와 동작원리가 같다. • const로 반복자를 선언하면 가리키는 대상을 보존한다. • 데이터의 상수성은 const_iterator를 사용하여 보존할 수 있다.
  15. 15. Item 3: 일단 const를 쓰고 생각한다. • 함수에서 const (1) • 반환값이 const • 불필요한 에러를 줄일 수 있다. • “훌륭한 클래스는 쓸데없는 비 호환성을 피한다.“ class Rational { const Rational operator*( const Rational& lhs, const Rational& rhs ); }; Rational a, b, c; ... If(( a * b ) = c){ … } //컴파일 에러
  16. 16. Item 3: 일단 const를 쓰고 생각한다. • 함수에서 const (2) • 상수 멤버 함수 • 상수 객체에서도 호출 가능한 함수 • 멤버 변수들의 값을 바꾸지 않음. • 함수의 상수성을 표현하는데 유익한 인터페이스 • 자주 쓰이는 const T&가 사용할 수 있는 함수
  17. 17. Item 3: 일단 const를 쓰고 생각한다. • 함수에서 const (3) • 일반 멤버 함수에 상수 멤버 함수를 오버로딩한다. • 상수 객체, 비 상수 객체 모두 상황에 따라 사용할 수 있도록. • ex) T의 배열 객체에서 operator[] • 비상수 멤버 함수 : const T& 리턴 • 상수 멤버 함수 : T& 리턴 ( 왜 T&인지는 알겠지? )
  18. 18. Item 3: 일단 const를 쓰고 생각한다. • 함수에서 const (3-1) • 오버로딩에서 코딩 중복을 피하는 방법 • 리턴 형식 빼고 거의 똑같은 코드라면? • 상수버전 함수를 호출하고 const_cast를 사용한다. • 비 상수 버전을 상수버전에서 호출하면 안된다. • 상수 멤버 함수의 상수성이 보존될 거라고 장담할 수 없음. char& operator[](std::size_t position) { return const_cast<char&> ( static_cast<const TextBlock&> ( *this )[position] ); }
  19. 19. Item 3: 일단 const를 쓰고 생각한다. • 함수에서 const(4) • 상수 멤버 함수의 물리적 상수성 • 객체를 구성하는 비트 값 변경 불가능  멤버변수에 대입연산 불가능 • 포인터 멤버 변수의 주소만 일치하면 OK  내용 변경 가능 • 불완전한 상수성
  20. 20. Item 3: 일단 const를 쓰고 생각한다. • 함수에서 const(5) • 상수 멤버 함수의 논리적 상수성 • 물리적 상수성을 보완하기 위해서 만든 개념 • 몇 개의 변수를 활용하여 직접 상수성 체크 • 상수성 검증에 필요한 변수들 변경가능해야함 • 이때 사용되는 것이 mutable • 어떤 상황에도 변경할 수 있는 변수임을 선언하는 키워드 size_t TextBlock::length() const { if(!lengthIsValid) { textLength = strlen(pText); lengthIsValid = true; } return textLength; }
  21. 21. 잊지 말자 초기화 ITEM 4
  22. 22. Item 4: 잊지 말자 초기화 • C( in C++ )의 자동 초기화를 믿지 말자 • 상황에 따라 초기화 할 때 있고 안 할 때 있음 • C( in C++ )의 초기화 규칙은 복잡 다난 • 초기화 되지 않은 값은 undefine behavior의 어머니 • 그러니까 항상 직접 초기화를 하자 • 일반 변수는 직접 손으로 초기화 • 클래스의 멤버변수들은 하나도 빠짐없이 생성자에서 초기화
  23. 23. Item 4: 잊지 말자 초기화 • 대입 vs 초기화 • 생성한 뒤에 값을 집어 넣으면 대입 • 생성할 때 값을 지정하면 초기화 • C++ 초기화 규칙 • “객체의 멤버는 생성자 본문이 실행되기 전에 초기화 되어야 한다.” • 생성자 호출 한 번 vs 생성자 + 대입연산 두 번. • 초기화 리스트 쓰세요
  24. 24. Item 4: 잊지 말자 초기화 • 초기화 리스트 • 초기화 리스트의 인자는 멤버 변수의 생성자의 인자로 처리 • 인자가 없으면 기본 생성자 호출 • 상수 혹은 참조자 타입 멤버는 필수적으로 초기화 필요. • 선언하는 헤더에서 초기화가 안된다면, 초기화 리스트로!
  25. 25. Item 4: 잊지 말자 초기화 • Class 멤버들의 초기화 순서 1. 부모 클래스가 자식 클래스보다 먼저 초기화 된다. 2. 클래스 멤버변수는 선언 순서로 초기화 된다. • 초기화 리스트에서 순서를 달리해도 초기화 되는 순서는 같다. • 빠른 오류 검출을 위해서 초기화 리스트 순서와 선언 순서를 맞춰준다. 3. 비지역 정적 객체의 초기화 순서는 개별 번역 단위에서 정해진다. • ???
  26. 26. Item 4: 잊지 말자 초기화 • 비 지역 정적 객체의 초기화 순서 문제 (해설편) • 비 지역 정적 객체 • 전역 객체, 네임스페이스 안의 전역 객체, 클래스의 정적 멤버 객체, 파일 유효범 위에 선언된 static 객체 • 번역 단위 • 전처리(#include) 까지 마친 목적파일의 단위 • 별개의 번역 단위에 있는 비 지역 전역 객체의 경우 • 한쪽이 초기화 되어도 다른 한쪽이 초기화 되었다고 보장할 수 없다.
  27. 27. Item 4: 잊지 말자 초기화 • 비 지역 정적 객체의 초기화 순서 문제 (해답편) • 비 지역 정적 객체가 문제라면 지역 정적 객체를 쓴다. • 함수를 사용해서 정적 객체의 참조자를 리턴 받아 사용. • 맨날 쓰는 Singletone 패턴 • 지역 정적 객체는 반드시 초기화 된 상태의 객체를 쓰도록 설계한다. • 안 필요하면 안 만들게 설계한다.
  28. 28. Item 4: 잊지 말자 초기화 • 쓰레드 프로그래밍에서 정적 객체 초기화는? • 어디서 어떻게 초기화될지 아무도 모른다. • 다중 쓰레드 돌입하기 전에 한번씩 GetInstance() 호출 • 객체 초기화 순서는 꼬이지 않게 알아서 잘 짜야한다. • A 초기화  B가 필요  B 초기화  A가 필요 (노답) • 이렇게 되어버리면 앞에서 말한 건 다 무 쓸모

×