28
EFFECTIVE C++ 정정 Chapter 1

Effective C++ Chaper 1

  • Upload
    -

  • View
    230

  • Download
    3

Embed Size (px)

Citation preview

Page 1: Effective C++ Chaper 1

EFFECTIVE C++ 정리Chapter 1

Page 2: Effective C++ Chaper 1

짬뽕 언어 C++ITEM 1

Page 3: Effective C++ Chaper 1

Item 1: 짬뽕언어 C++

• 다중 패러다임 프로그래밍 언어• 절차적 (procedure),

• 객체지향 (object-oriented),

• 함수형 (functional),

• 일반화 (generic),

• 메타프로그래밍 (meta-programming)

Page 4: Effective C++ Chaper 1

Item 1: 짬뽕언어 C++

• 다중 패러다임 프로그래밍 언어• 절차적 (procedure) C 언어 기반으로 제작

• 객체지향 (object-oriented) 클래스를 쓰는 C

• 함수형 (functional) 람다

• 일반화 (generic) 템플릿 , STL

• 메타프로그래밍 (meta-programming) TMP

Page 5: Effective C++ Chaper 1

Item 1: 짬뽕언어 C++

• 여러 하위 언어들의 연합 (FEDERATION)

• Divide And Conquer

• 단 하나의 정답은 없다 .

Page 6: Effective C++ Chaper 1

#define 쓰기 전에 잠깐만 ..ITEM 2

Page 7: Effective C++ Chaper 1

Item 2 : #define 쓰기 전에 잠깐만 ..

• #define 정의의 문제점• #define ASPECT_RATIO 1.653 //OUT

• 전처리기에 의해 단순 전치되는 값 .

• 컴파일 기호 테이블에 들어가지 않는다 .

• 컴파일 디버그에서 의미파악 불분명

• 사용할 때마다 사본 생성 (ex: 긴 문자열의 경우 )

Page 8: Effective C++ Chaper 1

Item 2 : #define 쓰기 전에 잠깐만 ..

• 일반 상수 변수를 사용하자• const double AspectRatio = 1.653;

• 컴파일러가 인식하는 기호

• 사본 생성 X

• const char* const authorName = “Scott Meyers”;

• 상수 포인터는 내용 상수성 체크

• 문자열 상수는 왠만하면 std::string 씁시다 .

Page 9: Effective C++ Chaper 1

Item 2 : #define 쓰기 전에 잠깐만 ..

• 클래스 멤버 상수면 static 쓰자 .

• 상수의 scope 를 클래스로 제한할 때

• 헤더에만 쓰면 정의 아니고 선언• 주소가 필요한 경우 cpp 에 정의 필요

• const int GamePlayer::NumTurns;

• 상수 초기화는 선언에 하는 것이 옳다

class GamePlayer { ... private:

static const int NumTurns = 5; ... };

Page 10: Effective C++ Chaper 1

Item 2 : #define 쓰기 전에 잠깐만 ..

• 정적 멤버 상수 못쓰는 경우• 컴파일러 구린건 정적 멤버 선언 시 초기화 못함 .

• 초기값을 상수 정의 시점에 주면 된다 .

• 클래스 컴파일 시점에 클래스 전용 상수가 필요하다면 ?

• Enum Hack! ( 나열자 둔갑술…이름 구림 )

• enum { NumTurns = 5};

• 마치 scope 가 있는 #define 마냥 사용할 수 있다 .

• TMP 에서 자주 사용되는 기법 .

Page 11: Effective C++ Chaper 1

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; }

Page 12: Effective C++ Chaper 1

일단 const 쓰고 생각한다 .ITEM 3

Page 13: Effective C++ Chaper 1

Item 3: 일단 const 를 쓰고 생각한다 .

• const 의 멋짐을 모르는 당신은 너무 불쌍해• 의미적 제약을 소스 코드 수준에서 붙일 수 있음

• const == “ 외부 변경 불가능”

• 이 제약을 컴파일러에서 처리함 .

• 빠른 오류 검출

• 전역 상수 정의 할 때도 사용됨 (item 2)

Page 14: Effective C++ Chaper 1

Item 3: 일단 const 를 쓰고 생각한다 .

• 복잡한 ( 것 처럼 보이는 ) 규칙• const( 데이터의 상수성 ) char * const ( 포인터의 상수성 )

• STL iterator 의 상수성• 반복자는 T * 와 동작원리가 같다 .

• const 로 반복자를 선언하면 가리키는 대상을 보존한다 .

• 데이터의 상수성은 const_iterator 를 사용하여 보존할 수 있다 .

Page 15: Effective C++ Chaper 1

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){ … } // 컴파일 에러

Page 16: Effective C++ Chaper 1

Item 3: 일단 const 를 쓰고 생각한다 .

• 함수에서 const (2)

• 상수 멤버 함수• 상수 객체에서도 호출 가능한 함수

• 멤버 변수들의 값을 바꾸지 않음 .

• 함수의 상수성을 표현하는데 유익한 인터페이스

• 자주 쓰이는 const T& 가 사용할 수 있는 함수

Page 17: Effective C++ Chaper 1

Item 3: 일단 const 를 쓰고 생각한다 .

• 함수에서 const (3)

• 일반 멤버 함수에 상수 멤버 함수를 오버로딩한다 .

• 상수 객체 , 비 상수 객체 모두 상황에 따라 사용할 수 있도록 .

• ex) T 의 배열 객체에서 operator[]

• 비상수 멤버 함수 : const T& 리턴

• 상수 멤버 함수 : T& 리턴 ( 왜 T& 인지는 알겠지 ? )

Page 18: Effective C++ Chaper 1

Item 3: 일단 const 를 쓰고 생각한다 .

• 함수에서 const (3-1)

• 오버로딩에서 코딩 중복을 피하는 방법• 리턴 형식 빼고 거의 똑같은 코드라면 ?

• 상수버전 함수를 호출하고 const_cast 를 사용한다 .

• 비 상수 버전을 상수버전에서 호출하면 안된다 .

• 상수 멤버 함수의 상수성이 보존될 거라고 장담할 수 없음 .

char& operator[](std::size_t position) { return const_cast<char&> ( static_cast<const TextBlock&> ( *this )[position] ); }

Page 19: Effective C++ Chaper 1

Item 3: 일단 const 를 쓰고 생각한다 .

• 함수에서 const(4)

• 상수 멤버 함수의 물리적 상수성• 객체를 구성하는 비트 값 변경 불가능 멤버변수에 대입연산 불가능

• 포인터 멤버 변수의 주소만 일치하면 OK 내용 변경 가능

• 불완전한 상수성

Page 20: Effective C++ Chaper 1

Item 3: 일단 const 를 쓰고 생각한다 .

• 함수에서 const(5)

• 상수 멤버 함수의 논리적 상수성• 물리적 상수성을 보완하기 위해서 만든 개념

• 몇 개의 변수를 활용하여 직접 상수성 체크

• 상수성 검증에 필요한 변수들 변경가능해야함

• 이때 사용되는 것이 mutable

• 어떤 상황에도 변경할 수 있는 변수임을 선언하는 키워드

size_t TextBlock::length() const { if(!lengthIsValid) { textLength = strlen(pText); lengthIsValid = true; } return textLength; }

Page 21: Effective C++ Chaper 1

잊지 말자 초기화ITEM 4

Page 22: Effective C++ Chaper 1

Item 4: 잊지 말자 초기화

• C( in C++ ) 의 자동 초기화를 믿지 말자• 상황에 따라 초기화 할 때 있고 안 할 때 있음

• C( in C++ ) 의 초기화 규칙은 복잡 다난

• 초기화 되지 않은 값은 undefine behavior 의 어머니

• 그러니까 항상 직접 초기화를 하자• 일반 변수는 직접 손으로 초기화

• 클래스의 멤버변수들은 하나도 빠짐없이 생성자에서 초기화

Page 23: Effective C++ Chaper 1

Item 4: 잊지 말자 초기화

• 대입 vs 초기화• 생성한 뒤에 값을 집어 넣으면 대입

• 생성할 때 값을 지정하면 초기화

• C++ 초기화 규칙• “ 객체의 멤버는 생성자 본문이 실행되기 전에 초기화 되어야 한다 .”

• 생성자 호출 한 번 vs 생성자 + 대입연산 두 번 .

• 초기화 리스트 쓰세요

Page 24: Effective C++ Chaper 1

Item 4: 잊지 말자 초기화

• 초기화 리스트• 초기화 리스트의 인자는 멤버 변수의 생성자의 인자로 처리

• 인자가 없으면 기본 생성자 호출

• 상수 혹은 참조자 타입 멤버는 필수적으로 초기화 필요 .

• 선언하는 헤더에서 초기화가 안된다면 , 초기화 리스트로 !

Page 25: Effective C++ Chaper 1

Item 4: 잊지 말자 초기화

• Class 멤버들의 초기화 순서1. 부모 클래스가 자식 클래스보다 먼저 초기화 된다 .

2. 클래스 멤버변수는 선언 순서로 초기화 된다 .

• 초기화 리스트에서 순서를 달리해도 초기화 되는 순서는 같다 .

• 빠른 오류 검출을 위해서 초기화 리스트 순서와 선언 순서를 맞춰준다 .

3. 비지역 정적 객체의 초기화 순서는 개별 번역 단위에서 정해진다 .

• ???

Page 26: Effective C++ Chaper 1

Item 4: 잊지 말자 초기화

• 비 지역 정적 객체의 초기화 순서 문제 ( 해설편 )

• 비 지역 정적 객체 • 전역 객체 , 네임스페이스 안의 전역 객체 , 클래스의 정적 멤버 객체 , 파일 유효범위에

선언된 static 객체

• 번역 단위• 전처리 (#include) 까지 마친 목적파일의 단위

• 별개의 번역 단위에 있는 비 지역 전역 객체의 경우• 한쪽이 초기화 되어도 다른 한쪽이 초기화 되었다고 보장할 수 없다 .

Page 27: Effective C++ Chaper 1

Item 4: 잊지 말자 초기화

• 비 지역 정적 객체의 초기화 순서 문제 ( 해답편 )

• 비 지역 정적 객체가 문제라면 지역 정적 객체를 쓴다 .

• 함수를 사용해서 정적 객체의 참조자를 리턴 받아 사용 .

• 맨날 쓰는 Singletone 패턴• 지역 정적 객체는 반드시 초기화 된 상태의 객체를 쓰도록 설계한다 .

• 안 필요하면 안 만들게 설계한다 .

Page 28: Effective C++ Chaper 1

Item 4: 잊지 말자 초기화

• 쓰레드 프로그래밍에서 정적 객체 초기화는 ?

• 어디서 어떻게 초기화될지 아무도 모른다 .

• 다중 쓰레드 돌입하기 전에 한번씩 GetInstance() 호출

• 객체 초기화 순서는 꼬이지 않게 알아서 잘 짜야한다 .

• A 초기화 B 가 필요 B 초기화 A 가 필요 (노답 )

• 이렇게 되어버리면 앞에서 말한 건 다 무 쓸모