모어이펙티브 C++ 5,6

8
More Effective C++ 5, 6

Transcript of 모어이펙티브 C++ 5,6

Page 1: 모어이펙티브 C++ 5,6

More Effective C++ 5, 6

Page 2: 모어이펙티브 C++ 5,6

유용하고 재미있는 기법들뒷부분!

Page 3: 모어이펙티브 C++ 5,6

프록시 클래스

어떤 객체를 대신하여 동작하게 하는 장치, 다음과 같은 기능을 구현할 때 사용한다.

다차원 배열

array[][] 형태의 다차원 배열을 구현할 때, 내부적으로 proxy[]형태의 클래스 사용

좌항값/우항값 구분

array[3] 이 쓰일 때, 값이 삽입되는 좌항에 위치한 값인지,

다른 값에 대입하거나 연산하기 위해 쓰는 우항 값인지를 구별

암시적 타입변환 방지

단점도 있다!!

프록시 객체가 임시객체이기 때문에 생성/소멸이 반복되는 비용

Page 4: 모어이펙티브 C++ 5,6

이중(다중) 디스패치 함수를 복수의 객체에 대해 가상 함수처럼 동작하게 만들기

함수를 입력받는 파라미터의 동적 타입에 따라 다른 기능이 수행되도록 만들 때, 어떻게 할 것인

가?

(특정 클래스를 상속한 객체들 간)

가상함수와 RTTI

충돌 처리하는 collide라는 함수가 필요할 경우 자식 클래스에서 collide(부모타입& object) 함

수를 만들고 함수 내부에서 typeid(object) 가 자식 클래스들 typeid(SpaceShip) 등등과 맞는

지를 판단하는 if ~ else문을 이용하여 별도 처리를 할 수 있도록 구현한다.

** 자식 클래스가 늘어날 때마다 수정해줘야 한다.. 유지보수 ↓

가상함수만 이용하여 구현

부모 클래스에서 가상함수를 이용 각각에 자식 클래스 타입에 맞는 collide를 오버로딩 한다.

** 마찬가지로 자식 클래스가 늘어나면 수정 + 전체를 다시 컴파일 해야 함

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

collide라는 함수를 만들고 collide가 실제 기능을 수행하는 함수들의 함수포인터를 참조해서 타

입에 맞는 기능을 수행

** 실제 collide기능을 수행하는 부분을 멤버함수로 하지 않고 밖으로 빼면, 상속구조에 다른 클

래스들이 추가되더라도 다시 컴파일하는 일을 막을 수 있음

Page 5: 모어이펙티브 C++ 5,6

이외의 이야기들

Page 6: 모어이펙티브 C++ 5,6

미래 지향적인 프로그래머가 되자

변화를 받아들이고 변화에 대비

문서화나 주석문 대신 c++의 특징을 이용, 사용자로 하여금 의도하지 않은 사용에 대한 제약을

두는 것.

(올바르게 쓰기는 쉽되, 의도치 않게 사용하는 것은 어렵게 만들자)

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

대입과 복사 생성을 모든 클래스에 대해 처리할 것.

아리송하면 int의 동작 원리대로 만들 것.(when in doubt, do as the ints do)

변경이 필요하면 그 영향이 제한된 부분에만 미치도록 설계, 캡슐화와 이름 없는 네임 스페이스

가상 소멸자가 없는 클래스를 상속하려 하지 말 것.(ex. stirng class)

** 가상 소멸자로 안 만든 이유가 있을 것임( string 같은 경우 vptr이 추가되면 크기가 두 배로-

char하나밖에 없음- 늘어나고 수행시간도 vtbl을 참조하는 덕분에 20%가량 증가한다고..)

Page 7: 모어이펙티브 C++ 5,6

non-leaf 클래스는 반드시 추상클래스로 만들 것.

부모클래스 animal과 자식 클래스들 간 대입 연산자 사용시

Animal *pAnimal1 = &liz1;

Animal *pAnimal2 = &liz2;

*pAnimal1 = *pAnimal2;

같은 구문에서 실제 호출되는 operator=이 animal class의 것이므로 그에 해당하는 부분만 복

사되고 lizard class에 해당하는 부분을 잘릴 수 있음.

operator= 을 virtual로 만든다면

자식 클래스들 간의 불일치 대입이 가능해짐(*lizard = *chicken 같은거)

operator=을 부모 클래스에서 private으로 만들면?

자식 클래스 operator=구현시 부모클래스의 operator=을 갖다 쓸 수 없고

타입을 체크하기 위해 dynamic_cast를 사용해주어야 함.

그럼 어떻게 하라고..ㅠㅠ

animal을 abstractAnimal같은 추상클래스로 만들고

실제 animal의 내용은 그 자식클래스인 animal로 구현할 것.

Page 8: 모어이펙티브 C++ 5,6

한 프로그램에서 C++과 C를 함께 사용하는 방법을 이해

네임 맹글링(Name Mangling)

C함수는 Name Mangling을 하지 않는다. 하지만 C++함수는 overiding을 하기위해 컴파일러

에서 Name Mangling을 통해 다른 이름으로 변경해준다. 문제는 C로 만들어진 함수를 C++에

서 사용할 때 해당 함수를 name mangling해버리면 목적파일이나 라이브러리에서는 못 찾는다

는 것이다. (걔들은 원래 함수의 이름을 가지고 있을 것이므로 )

이럴경우 extern C 지시자를 사용해서 mangling을 막자

정적 데이터 초기화

C++ 컴파일러는 main함수 위아래로 정적 데이터를 초기화하는 부분을 따로 넣음

C컴파일러는 그렇지 못한데 main함수를 부득이하게 C로 짜야하는 경우

C++로 된 메인에 C로된 실제 main구문을 호출하는 방식으로 해결할 수 있음

동적할당

malloc – free new – delete는 쌍을 맞춰서 사용할 것.

자료의 호환성

가상 함수와 관련 있는 클래스나 구조체는 호환성 문제를 일으킬 수 있다.