Chapter 4 설계 및 선언


* 인터페이스 설계는 제대로 쓰기는 쉽게, 엉터리로 쓰기에는 어렵게 한다.

예를들어 어떤 객체나 함수에 값을 전달하는데 잘못된 값 또는 잘못된 범위를 입력하면 오류가 발생하도록 만드는 등의 설계가 필요함.


* 멤버함수에서 객체를 생성하는 경우 객체의 포인터를 반환하기 보다 애초에 스마트 포인터를 반환하는 것이 문제의 소지를 덜 발생시킨다.


* 실수를 방지하는 방법

- 새로운 타입 만들기

- 타입에 대한 연산을 제한하기

- 객체의 값에 대해 제약 걸기

- 자원 관리 작업을 사용자 책임으로 놓지 않기


* 스마트포인터(shared_ptr)은 교차 DLL 문제를 미연에 방지해준다.


* 값에 의한 전달(pass-by-value)보다는 상수객체 참조자에 의한 전달(pass-by-reference) 방식을 택하는 편이 대개 낫다.

- 값에 의한 전달로 객체를 받을 경우 복사생성자에 의해 생성되며 다시 소멸이 이루어진다. 엄청난 비용이 소모됨. 복사손실 문제까지 막아준다.

- 기본제공 타입(char, int 등), STL 반복자, 함수객체 타입에 대해서는 값에 의한 전달이 더 적절하다.



Chapter 3 자원관리


* 자원을 획득(동적할당)한 뒤에는 자원관리 객체에게 넘긴다. 그 후 소멸자를 통해 확실히 해제되도록 한다. 스마트 포인터를 사용하면 좋다.


* 자원관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 한다.


* 스마트 포인터를 매개변수로 넘길 경우에는 get함수를 이용하여 명시적으로 변환 후 넘겨줘야 한다.


* RAII (자원획득 즉 초기화) 클래스가 자원 접근 함수를 열어주는것이 캡슐화의 위배는 아니다. 애초에 RAII 클래스는 데이터 은닉이 목적이 아니기 때문이다.


* new-delete를 사용하면 메모리 할당->생성자 호출->소멸자 호출->메모리 해제 순으로 작동된다.


* new에 []를 사용하여 할당했다면 delete에도 반드시 []를 붙여서 깔끔하게 해제해야 한다.


* 배열 타입은 typedef로 만들지 않는것이 좋다. (ex ; typedef int iArray[4];)


* new로 생성한 객체의 포인터를 스마트포인터에 저장하는 코드는 별도의 한 문장으로 만들어준다. 스마트포인터의 생성자는 explicit로 선언되어 있기 때문에 명시적인 변환만 허용된다.

- ex1) processWidget(new Widget, priority()); (암시적인 변환이므로 컴파일 안됨)

- ex2) processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority()) (명시적인 변환이므로 컴파일 가능)

ex2) 와 같은 경우에는 메모리 누수에 대한 위험성에 노출되어있기 때문에 독립적인 문장으로 만들어주고 해당 스마트포인터를 인자로 넘겨준다.

Chapter 2 생성자, 소멸자 및 대입 연산자


* 생성자를 정의해주었다면 기본 생성자를 만들어내지는 않음


* 참조자를 데이터 멤버로 갖고있는 클래스에 대입 연산을 지원하려면 직접 복사 대입 연산자를 정의해 주어야 함.


* 복사 대입 연산자를 private으로 선언한 클래스를 상속한 클래스의 경우, 암시적인 복사대입 연산자를 가질 수 없음.


* 위의 특성을 이용하여 복사 생성자와 복사 대입 연산자를 private에 선언 후 정의를 해버리지 않으면 복사 생성자와 복사 대입 연산자의 사용을 막을 수 있음.


* 링크 시점 에러를 컴파일 시점 에러로 옮길 수도 있음.


* 다형성을 가진 기본클래스에서는 소멸자를 반드시 virtual로 선언할 것. 그렇지 않으면 기본객체 포인터로 객체 삭제를 시도했을 시 기본객체의 소멸자만 호출되어서 자식객체는 삭제되지 않고 메모리 누수가 발생된다. (기본클래스에만 써주면 됨)


* virtual 소멸자를 선언하는 것은 해당 클래스에 가상함수가 하나라도 들어 있는 경우로 한정해야 함. 가상함수가 포함되면 객체의 크기가 커진다.


* 가상 소멸자가 없는 클래스는 STL 컨테이너 타입들이다. 그러니 컨테이너 타입들을 상속받아서 사용하지 말자.


* 소멸자에서 절대 예외가 빠져나가지 않도록 try-catch를 이용하자.


* 예외에 대해 사용자가 반응해야 할 필요가 있다면 반드시 보통의 함수에서 처리하는것이 좋다.


* 파생클래스의 기본클래스가 생성되는 도중의 해당 객체 타입은 기본클래스이다.


* 객체 생성 및 소멸과정에서 절대로 가상함수를 호출하지 말자.


* 미초기화된 데이터 멤버는 정의되지 않은 상태에 있다. 이때문에 객체의 생성 및 소멸시에 가상함수가 파생클래스로 내려가지 않는 것이다.


* 대입 연산자는 *this의 참조자를 반환하도록 한다.


* operator= 에서 자기대입에 대한 처리를 반드시 한다.


* 객체의 복사는 모든 부분을 빠짐없이 복사해야한다. 얕은 복사와 깊은 복사에 대한 문제도 고려해야한다.


Chapter 1 C++에 왔으면 C++의 법을 따릅시다


* const, enum, inline으로 #define을 얼마든지 대신할 수 있다. 또한 대신해서 쓰는게 더 안정성이 좋다.


 정적멤버로 만들어지는 정수류 타입의 클래스 내부 상수는 정의가 아닌 선언이다. 해당 멤버의 주소를 구하거나 할 때에는 정의를 따로 해주어야 한다.


* const가 붙는 위치에 따라 의미가 조금 달라진다.

const int *ip : 타입이 상수, 포인터는 비상수이므로 포인터가 가리키는 대상의 값이 상수화된다. 가리키는 대상이 변경되어도 문제 없음.

int const *ip : 타입이 비상수, 포인터는 상수이므로 포인터가 가리키는 대상 자체가 상수화된다. 가리키는 대상이 변경되면 에러가 발생된다. 가리키는 대상의 값을 변경하는것은 문제 없음.


* 멤버함수에 붙는 const의 역할은 해당 멤버함수가 상수객체에 대해 호출될 함수라는 사실을 알려주는 역할이다.

const 키워드가 있고 없고의 차이만 있는 멤버함수들은 오버로딩이 가능하다.


* 멤버함수가 상수함수라는 의미의 개념은 비트수준 상수성(물리적 상수성)과 논리적 상수성이다.

비트수준 상수성 : 멤버함수가 그 객체의 어떤 데이터 멤버도 건드리지 않아야 상수임을 인정. (정적멤버 제외)

논리적 상수성 : 객체의 일부 몇비트 정도는 바꿀수있되, 사용자측에서 알아채지 못하게만 하면 상수멤버 자격 인정.


 상수/비상수 멤버함수의 코드중복을 피하기 위해 두번의 캐스팅을 사용하여 코드중복을 없앤다. (비상수 멤버함수 안에서 static_cast로 상수성을 부여하여 상수멤버함수의 함수를 실행한 후 const_cast로 상수성을 뗀 값을 반환하면 됨)


 초기화와 대입은 엄연히 다르다. TextBlock(std::string str) : text(str) {} 이런게 초기화임. 이런 방식은 복사 생성자에 의해 초기화 되는것이 원리임. 기본 생성자로 초기화하고 싶으면 생성자 인수로 아무것도 주지 않으면 됨.


 초기화 리스트에 의해 초기화 될 시, 초기화 되는 순서는 선언한 순서대로 초기화된다. 혼동을 방지하기 위해 선언과 초기화리스트 순서를 동일하게 맞춰주는 것이 좋다.


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

정적 객체 : 전역 객체, 네임스페이스 유효범위에서 정의된 객체, 클래스 안에서 static으로 선언된 객체, 함수안에서 static으로 선언된 객체, 파일 유효범위에서 static으로 정의된 객체.

함수안에 있는 정적 객체를 지역 정적 객체라고 한다. 그 외의 모든것은 비지역 정적 객체.


* 비지역 정적 객체를 하나씩 맡는 함수를 만들어서 참조자를 반환하게 만들어서 사용하면 초기화 되는 순서를 프로그래머가 잡아줄 수 있다.

반갑습니다


군입대 및 휴학이 길어짐에 따라 잠시 전공에서 멀어져있는 관계로 블로그에 신경을 쓰질 못했습니다


내년에 다시 복학함에 따라 블로그를 다시 활성화시켜야할 필요가 있는 것 같아서 다시 정보를 차근차근 모아보려 합니다


이 블로그의 목적은 정보공유 뿐만 아니라 개인적인 공부 및 전공지식 향상에 목적을 두고 있습니다

'소소한이야기' 카테고리의 다른 글

이런... -_-  (0) 2012.08.05
2011 버그소프트 서울 선후배모임 사진  (0) 2012.01.06
OpenGL로 배우는 컴퓨터 그래픽스  (0) 2011.09.01
진행중인 인지 증강현실 프로젝트  (0) 2011.08.29
카메라 구입  (0) 2011.06.22

+ Recent posts