more effective c++ 항목30부터

22
more Effective C++ Chapter 5 항목 30부터 ‘유용하고 재미있는 프로그래밍 기법들_2와 이외의 이야기들’ 131039 신동찬

Upload: dongchan-shin

Post on 29-Jun-2015

901 views

Category:

Engineering


19 download

DESCRIPTION

more effective c++ 최종 과제

TRANSCRIPT

Page 1: More effective c++ 항목30부터

more Effective C++ Chapter 5 항목 30부터‘유용하고 재미있는 프로그래밍 기법들_2와 이외의 이야기들’

131039 신동찬

Page 2: More effective c++ 항목30부터

안그래도 X,Z좌표로 이루어진Height Map 만드는데...개발자의 색감

잘 걸린 PROXY 클래스

Page 3: More effective c++ 항목30부터

2차원 배열 클래스를 제작하기 위해내부에 1차원 배열 클래스를 두어1차원 배열의 1차원 배열로 구현하는 2차원 배열

또 다른 객체를 대신하는 객체를 두는 방법을프록시 객체라고 하고객체를 생성하는 클래스를 프록시 클래스라 함

예제에서는내부에 있는 1차원 배열 클래스를 프록시라고 할 수 있음

Page 4: More effective c++ 항목30부터

프록시 클래스의 국가대표급 응용 사례

Operator[]의 읽기/쓰기 동작을 구분하는 것

여기서 잠깐!Lvalue, Rvalue에 대해서 이해 하는 것 잊지마세요

http://kholdstare.github.io/technical/2013/11/23/moves-demystified.html

Page 5: More effective c++ 항목30부터

프록시 클래스로 읽기 쓰기 구분이 단순하지 않습니다.29장에서 봤던 방법으로는 해결이 안됩니다.

아래 코드에서 멤버 함수의 호출 상태를 고려하지 않는다는 문제!

그래서 지연평가를 활용해야 하는데지연 시간을 벌어주는 일이 프록시 클래스 역할

operator[]호출 후 반환 프록시가 어떻게 사용되나 확인 후읽기/쓰기를 구분 짓는 것

Page 6: More effective c++ 항목30부터
Page 7: More effective c++ 항목30부터

하지만 여전히 문제가 있어요반환 값의 타입이 바뀌게 되면 또 컴파일 에러가 나옵니다

해결 방법은해당 클래스의 주소 연산자 오버로딩

그런데 이런 상황은 대입 연산 대상으로는 괜찮은데+=, ++ *=, <<= 등등에서는...또 오류가 나오네요

필요한 연산자를 모두 정의해야 되는 문제가 있음

Page 8: More effective c++ 항목30부터

또 다른 문제!

반환 값이 프록시 객체이기 때문에 생각한 동작이 안 나온다

원래 객체에 적용할 수 있는 함수를 모조리 오버로딩

그래도 또!비상수 객체 참조자를 받는 함수의 매개변수로 프록시를 넘기면...

Page 9: More effective c++ 항목30부터

그래서 설계 단에서 거부되는 경우도 있다고 하네요

하지만 잘 쓰면 유용하니 오류가 날 부분을 확인하고 쓰세요

Page 10: More effective c++ 항목30부터

함수를 두 개 이상의 객체에 대해 가상 함수처럼 동작하도록 하기= 이중 디스패치 만들기

SKYLAB스러운 예제와 함께 보겠습니다우주의 서로 다른 객체가 충돌하는 함수 예제

원하는 내용을 다시 정리하면동적으로 객체 간 충돌을 구현하고 싶은 것

단, 새로운 객체 타입이 생기는 경우코드 변화가 최소여야 함

Page 11: More effective c++ 항목30부터

가상 함수 테이블의 유사 구현을 활용

map 자료구조에서 이름과 함수 객체를 가짐들어오는 이름에 따라서 해당 함수 객체를 실행함

자료의 생성주기는 정적 데이터로 선언하면프로그램의 생성과 소멸이 자동으로 해결

Page 12: More effective c++ 항목30부터

map을 만들고 접근하는 건 알겠는데초기화가 되어 있어야 하지 않나요?

어떻게 Handle할지 결정할 데이터로 채워야 합니다.

충돌 처리 함수가 클래스 멤버인 경우새로운 파생 클래스가 게임에 추가되면여전히 클래스 정의를 수정해야 하는 문제가 있음

=> 충돌 처리 함수를 밖으로 뺀다면?!

Page 13: More effective c++ 항목30부터

이름 없는 네임스페이스가 포인트컴파일 단위에서만 의미를 가지고 외부에서 확인 못 함

즉 함수 앞에 static을 붙여 정적 함수로 선언한 것과 같음

충돌처리 함수를 정적 영역에서 처리

Page 14: More effective c++ 항목30부터

그런데... 객체에 또 상속 받는 자손들이 생기면?!그래서 구조를 다시 바꿔 봤습니다

클래스의 객체가 전역메모리에 올라오는 동시에필요한 함수가 자동으로 등록 되는 형태

Page 15: More effective c++ 항목30부터

하지만 처음 의도처럼 완벽하지는 않습니다.

다중 디스패치를 완벽하게 구현하는 방법은 없습니다.그나마 그존 코드를 거의 변경하지 않는 방법이 있죠

Page 16: More effective c++ 항목30부터

미래 지향적인 개발자?!미래 지향적인 프로그래머?!

정확할 건 정확하게 해주는 것위험한 것을 경계하는 것에서 시작

• C++ 특징으로 못할 것은 막아 버림절대 상속이 일어나지 않는 클래스는 막아버리고힙에 인스턴스가 생성 되어야 하면 힙에만 만들어 지도록복사, 대입이 불필요하면 private 선언으로 틀어 막는 등

• 멀쩡한 함수를 가상함수로 만들지 말 것

• 대입 복사 생성은 컴파일러가 기본으로 만들어 버림필요 없으면 확실히 제거

• 코드 이식성 유지• 캡슐화

기조: 황당함 최소화의 원칙

Page 17: More effective c++ 항목30부터

이외에도...

• B*가 실제로 D를 가리키는 경우에만 B에 대한 가상 소멸자가 필요합니다• 다중 상속이 이루어진 클래스 계통 구조에 소멸자가 한 곳에라도 끼여 있으면

모든 기본 클래스에는 가상 소멸자가 들어가야 함• String클래스는 vtbl을 추가하고 싶지 않아 가상 소멸자가 아니다

등등...

완벽한 코드를 만들기 위한 일반적인 이야기들

더 자세한 내용은 책을 통해

Page 18: More effective c++ 항목30부터

어라?우리는 C++ 게임 만들고 있었는데요...

C와 C++는 당연히 뗄수 없는 관계다하지만 한 프로그램에서 사용할 때 주의할 점은

분명히 존재한다

Page 19: More effective c++ 항목30부터

• 네임 맹글링• 정적 데이터 초기화• 동적 메모리 할당• 자료구조 호환성

C++로 업그레이드 되며 생기거나 변환된 녀석들이문제를 일으킬 가능성이 있다!

해결책!

• 컴파일러가 생성하는 목적 코드 호환성 확인• 두 언어에서 동시 사용되는 함수는 extern “c”선언

(네임 맹글링 방지)• main은 C++로 작성• new로 할당된 메모리는 delet로

malloc으로 할당된 메모리는 free로• 전달 데이터 타입은 C로 컴파일 되는 것으로 만

Page 20: More effective c++ 항목30부터

C++ 언어의 최신 표준안과 표준라이브러리에 대해 익숙해지자.

여기서 이야기하는 최신은?!

아.. 네 10년전?!

Page 21: More effective c++ 항목30부터

이미 VS2013에는 많은 것이 적용되었고effective c++ 개정판에 포함된 내용도 많아요

현재 기술이라 생각하고 한 번 보시면 될 것 같습니다(책 보세요)

Page 22: More effective c++ 항목30부터

more effective C++ 끝.