Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Effective C++ Chapter 2 Summary

7 vues

Publié le

Effective C++ Chapter 2 Summary

Publié dans : Ingénierie
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Effective C++ Chapter 2 Summary

  1. 1. Choi Seung Yeon Chapter 2
  2. 2.  Item 5  Item 6  Item 7  Item 8  Item 9  Item 10  Item 11  Item 12
  3. 3. Item 5 : 자동으로 생성되는 함수들을 신경쓰자! [ class의 생성자, 소멸자, 복사 생성자, 복사 대입 연산자는 자동 생성된다 ] Default 생성자 / 소멸자 - 직접 정의한 생성자나 소멸자가 없으면 생성된다. - Base Class의 생성자 / 소멸자 호출과 비정적 데이터 멤버들의 기본 생성자 / 소멸자를 호출한다. - Base Class 소멸자가 virtual 이었다면, 똑같이 virtual로 생성한다.
  4. 4. Item 5 : 자동으로 생성되는 함수들을 신경쓰자! [ class의 생성자, 소멸자, 복사 생성자, 복사 대입 연산자는 자동 생성된다 ] 복사 생성자, 복사 대입 연산자 - 필요한 경우에만 자동으로 생성된다. (복사, 대입 등 연산이 있는 경우) - 기본 내장 타입 (int 등)은 비트 수준 복사를 수행한다. - 하지만 String과 같은 타입은 해당 타입의 복사 생성자가 호출된다. - Base Class의 복사 대입 연산자가 private이거나 클래스 멤버 중에 상수, 참조 타입 멤버가 있다면 자동 으로 생성되지 않는다. (C++의 참조자는 원래 참조하고 있는 것과 다른 객체를 참조할 수 없다.)
  5. 5. Item 6 : 자동 생성된 함수가 필요 없다면 버려라! [ 필요 없는 함수는 private에 선언하고 정의하지 않는다 ] 자동 생성되는 복사 생성자나 복사 대입 연산자를 원하지 않는 경우가 있다. 그럴 때는 private에 선언하고 정의하지 않으면 된다. (싱글톤 패턴에서 이용) 만약 복사를 시도하면 링킹 중에 에러가 발생한다.
  6. 6. Item 7 : 다형성을 가진다면 반드시 가상 소멸자! [ Base Class가 다형성을 가진다면 가상 소멸자를 반드시 사용한다 ] 가상 소멸자를 사용하지 않으면, 정적 바인딩과 동적 바인딩의 차이로 인해 제대로 객체의 소멸이 이루어지 지 않는다. 따라서 메모리 릭이 생기므로 반드시 가상 소멸자를 사용해야 한다. 또한, 가상 소멸자를 사용해야 소멸이 순서대로 일어난다. (Derived -> Base) 단, 다형성을 가진 Base Class에만 해당한다. (Base Class 인터페이스로 Derived Class를 조작 하는 경우)
  7. 7. Item 8 : 예외는 소멸자에서 처리해라! [ 소멸자 안의 예외는 소멸자 안에서 끝내자 ] Vector와 같은 container를 소멸시킬 때, 많은 소멸자가 호출된다. 이 경우 만약 소멸자 안에서 예외가 발 생했는데 처리하지 않는다면 큰 문제가 된다. 따라서, 소멸자 안에서 발생한 예외는 소멸자 밖에서 처리하는 것이 아니라 소멸자 안에서 처리해야 한다.
  8. 8. Item 8 : 예외는 소멸자에서 처리해라! [ 예외 처리 방법 1 ] 예외가 발생하면 바로 프로그램을 끝낸다. try{ … } catch { std::abort(); } [ 예외 처리 방법 2] 예외를 삼킨다. 즉, 로그만 남기고 진행시킨다. (이 경우, 예외를 무시해도 프로그램이 신뢰성 있게 실행이 되어야 한다) try{ … } catch { log(“Error!!!”); }
  9. 9. Item 8 : 예외는 소멸자에서 처리해라! [ 예외 처리 방법 3 : 따로 분리하여 사용자에게 맡겨라 ] 앞의 두 방법은 예외가 생기게 된 근본적인 원인에 대해 전혀 해결하고 있지 않다. 따라서 예외가 발생할 여지가 있다면, 그 부분을 함수로 따로 뺀다. 사용자는 그 함수를 이용하여, 직접 예외를 처리할 수 있다.
  10. 10. Item 9 : 객체 생성, 소멸 시 절대로 가상함수 호출 X! [ 생성자 호출 순서는 Base -> Derived 이다 ] 생성자 호출 시, Base Class 생성자 처리 중에는 불려진 클래스가 Derived 더라도 Base Class 인 것처럼 취급된다. 따라서, 이 때 가상함수를 호출해도 동적 바인딩이 되지 않는다. 즉, 객체 타입이 Derived Class 이지만, Base Class 생성자 처리 중에는 Base Class 취급이 되어 Base Class의 함수가 호출된다. 절대로 Derived Class의 함수가 호출되지 않는다. 생성자에는 가상함수를 쓰는 것은 피해야 한다.
  11. 11. Item 10 : 대입 연산자는 *this의 참조자 반환! [ *this의 참조자를 반환하면 연쇄 대입이 가능하다 ] 기본 내장 타입인 int는 다음과 같은 동작이 가능하다. int x, y, z; x = y = z = 10; 클래스도 똑같이 동작하게 하려면, 대입 연산자가 *this의 참조자를 반환하게 만들면 된다. Widget& operator += (const Widget& rhs) { … return * this; }
  12. 12. Item 11 : 자기대입 처리를 반드시 만들어라! [ operator= ] 코딩 중에 많은 오류가 발생하는 케이스가 자신에게 자기 자신을 대입하는 것이다. 이 경우를 예외처리 해 야만 나중에 문제를 일으키지 않는다. (자기 대입은 legal 처리가 되기 때문에, 더 문제다) [ 해결 방법 1 : 일치성 검사 ] 자기대입을 검사하여 예외를 처리한다.
  13. 13. Item 11 : 자기대입 처리를 반드시 만들어라! [ 해결 방법 2 : 포인터가 가리키는 객체 복사 직후 삭제 ] new 연산에서 예외가 터져버리면, 바로 앞에서 delete 된 객체를 가리키는 포인터만을 남기게 된다. 따라서, 포인터가 가리키는 객체를 복사한 직후에 삭제하면 문제를 해결할 수 있다. new 연산 중 예외가 발생해도 pData는 보존되기 때문에 안전하다.
  14. 14. Item 11 : 자기대입 처리를 반드시 만들어라! [ 해결 방법 3 : copy & swap ] 자기대입은 생각보다 많이 발생하지 않는다. 따라서 앞의 방법들은 비효율적이다. 그냥 두 데이터를 swap 하는 것이 효율적이다. 사본을 만들고 현재 객체와 사본을 swap 한다.
  15. 15. Item 12 : 객체를 완벽하게 복사하자! [ 직접 복사 생성자 / 복사 대입 연산자를 만든다면 복사를 철저히 하자 ] 컴파일러가 자동으로 생성하는 경우, 복사는 완벽하게 일어난다. 하지만 사람이 직접 만들면, 꼭 실수가 생 기기 마련이다. 아래 체크리스트를 꼭 확인하자. - 해당 클래스의 데이터 멤버를 모두 복사했는지 확인하자. - Base Class의 복사 함수도 제대로 호출 했는지 확인하자. Base Class의 데이터는 private로 선언되어 접근할 수 없는 경우가 많다. 따라서 제대로 복사함수를 호출 하여 복사를 해야 한다.

×