일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 루아
- reference
- UE4
- implicit conversion
- more effective c++
- 비교 함수 객체
- 상속
- operator new
- 메타테이블
- 오블완
- Effective c++
- 영화
- 게임
- 반복자
- 암시적 변환
- 영화 리뷰
- resource management class
- Vector
- 언리얼
- c++
- virtual function
- exception
- 예외
- effective stl
- 참조자
- 다형성
- Smart Pointer
- lua
- 스마트 포인터
- 티스토리챌린지
- Today
- Total
목록개발/Effective C++ (55)
스토리텔링 개발자
항목 15. 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자. 제대로 만들어진 스마트 포인터 클래스는 거의 모두 포인터 역참조 연산자도 오버로딩하고 있어서 사용 시의 편의를 제공한다.T* operator->() constT& operator*() const그럼에도 RAII 클래스의 객체를 실제 자원으로 변환해야 할 때가 있다.기존에 쓰이던 API에서 자원을 직접 참조하게 만들어져 있는 경우가 잦기 때문 변환 방법명시적 변환멤버 함수 제공.class Font{public: ... FontHandle get() const { return f; } // 명시적 변환 함수 ...}사용자가 하부 수준 API를 쓰고 싶을 때마다 get을 호출해야 하는 번거로움이 있다...
항목 14. 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자. 커스텀 자원 관리 클래스자원 관리 클래스를 직접 만들 필요성을 느낄 때가 있다.힙에 생기지 않는 자원은 기존 스마트 포인터로 관리하는 데 맞지 않다. 커스텀 자원 관리 클래스의 복사 동작RAII 법칙(생성시 자원 획득, 소멸시 자원 해제)을 따르는 클래스의 복사 동작복사를 금지한다.RAII 객체의 복사 자체가 말이 안되는 경우가 많다.뮤텍스 잠금의 경우 복사될 필요성 자체가 없다.복사되면 안되는 RAII 클래스는 반드시 복사 함수를 막아야 한다.Uncopyable을 사용하여 복사를 막는다.(항목 6 참조)class Lock : private Uncopyable // 항목 6 참고{public:...};관리하고 있는 자원에 대해 ..
항목 13 : 자원 관리에는 객체가 그만! new / delete 문의 짝을 맞추지 못하게 되는 상황class Investment { ... };Investment* createInvestment();void f(){ Investment* pInv = createInvestment(); ... // pInv 사용부. // 하지만 이 도중에 아래로 가지 않고 리턴해버릴 여지가 있다!! delete pInv; // 반드시 불러줘야 객체가 해제된다.}객체 삭제는 실패할 수 있는 경우가 다양하다.삭제 전에 return문이 들어있는 경우삭제 전 continue 혹은 goto로 루프를 갑작스래 빠져나왔을 경우사용 중에 예외가 발생할 경우 스마트 포인터void f(){ ..
항목 12. 객체의 모든 부분을 빠짐 없이 복사하자 복사 함수(copying function)복사 생성자복사 대입 연산자 커스텀 복사 함수의 맹점컴파일러가 생성한 복사 함수의 경우복사되는 데이터가 갖는 데이터를 빠짐없이 복사한다.커스텀 복사 함수의 경우기존에 아무리 꼼꼼히 모든 멤버를 복사하도록 구현하더라도 클래스에 멤버가 추가되거나 하여 부분 복사가 될 여지가 있다.이 경우 컴파일러는 경고 하나 띄우지 않음즉 클래스에 데이터 멤버 추가 시 복사함수 / 생성자 / 비표준형 operator= 갱신을 해줘야 할 필요성이 있다. 클래스 상속의 커스텀 복사class Customer // 기본 클래스{public: ...private: std::string name; Data lastT..
항목 11. operator = 에서는 자기 대입에 대한 처리가 빠지지 않도록 하자 자기 대입자기 자신에 대해 대입 연산자를 적용하는 것. 자기 대입에 대한 처리가 필요한 이유중복 참조 때문에 자기 대입이 생길 수 있다.int i = 1;int& ci1 = i;int& ci2 = i;ci1 = ci2; // 중복참조로 인한 자기대입같은 타입 객체 여럿을 참조자 / 포인터로 사용하는 코드를 작성할 때는 같은 객체가 사용될 가능성을 고려해야 한다. 자기 대입 문제의 예시class Bitmap { ... };class Widget{private: Bitmap* pb;};Widget& Widget::operator=(const Widget& rhs){ delete pb; pb = ne..
항목 10. 대입 연산자는 *this의 참조자를 반환하게 하자 대입 연산대입 연산은 사슬처럼 엮일 수 있다.x = y = z = 15;즉, 대입 연산은 우측 연관(right-associative) 연산이다. x = (y = (z = 15));즉, 아래 순서대로 동작한다.15가 z에 대입z가 y에 대입y가 x에 대입이를 위해 관례적으로 대입 연산자는 좌변 인자에 대한 참조자를 반환하도록 구현되어 있다.그러므로 별 이유가 없다면 *this의 참조자를 반환하도록 하자.
항목 9. 객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자 파생 클래스에서 호출되는 기본 클래스 생성자 문제기본 클래스 생성 중엔 가상 함수가 먹히지 않는다.기본 클래스의 생성자가 호출될 동안, 가상 함수는 절대로 파생 클래스로 내려가지 않는다.기본 클래스 부분이 생성되는 중엔 객체의 타입이 기본 클래스로 인지된다.가상함수가 기본 클래스의 것으로 호출된다.런타임 타입 정보를 사용하는 언어 요소(dynamic_cast, typeid 등)에서도 기본 클래스 타입의 객체로 취급한다.#include #include class A{public: A(){ std::cout 기본 클래스에서는 파생 클래스의 데이터가 아직 초기화되지 않았으므로 없었던 것처럼 취급하는 것이 안전하다..
항목 8. 예외가 소멸자를 떠나지 못하도록 붙들어 놓자. C++은 예외를 내보내는 소멸자를 좋아하지 않는다.'소멸자에서 예외 발생'은 미정의 사항이다.(컴파일러 구현에 따라 다르게 반응한다.)그러므로 소멸자에서는 예외를 던지지 않도록 처리해야 한다. 소멸자가 예외를 던지지 않게 하는 두 가지 방법예외 발생 시 프로그램을 종료시킨다에러 발생 후 프로그램 실행을 계속할 수 없는 상황이라면 이 선택지예외를 삼켜버린다발생한 예외를 무시해도 프로그램이 신뢰성 있게 실행 지속되어야 한다는 보장이 된다면 이 선택지catch에서 어떤 처리도 해주지 않음으로써 예외를 삼켜버릴 수 있다. 소멸자에서 예외 발생하는 부분을 “사용자가 제어할 수도 있게” 함수를 제공해준다.사용자에게 예외 처리를 처리할 수 있는 선택..