일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 루아
- exception
- lua
- effective stl
- 메타테이블
- operator new
- 비교 함수 객체
- reference
- virtual function
- 상속
- 영화 리뷰
- 반복자
- 티스토리챌린지
- 스마트 포인터
- 암시적 변환
- 다형성
- resource management class
- 게임
- 오블완
- implicit conversion
- 함수 객체
- Effective c++
- 예외
- more effective c++
- 언리얼
- UE4
- c++
- Smart Pointer
- 참조자
- 영화
- Today
- Total
목록개발 (181)
스토리텔링 개발자
항목 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에서 어떤 처리도 해주지 않음으로써 예외를 삼켜버릴 수 있다. 소멸자에서 예외 발생하는 부분을 “사용자가 제어할 수도 있게” 함수를 제공해준다.사용자에게 예외 처리를 처리할 수 있는 선택..
항목 7. 다형성을 가진 기본클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자. 기본 클래스의 소멸자가 비가상 소멸자라면기본 클래스 포인터에 할당된 파생 클래스 객체가 삭제될 때의 프로그램 동작이 미정의 사항(C++ 규정으로 정해져 있지 않다) 이다.그러므로 가상 함수를 하나라도 가진 클래스는 가상 소멸자를 가지는 것이 대부분 올바른 선택이다. 기본 클래스로 의도하지 않은 클래스에 가상 소멸자를 선언하는 건 좋지 않다.객체의 크기가 커진다.가상 함수를 하나라도 가지는 클래스는 가상 테이블(vtbl)의 시작 주소(vptr)를 가지게 되기 때문이다.다른 언어로 선언된 동일한 자료구조와의 호환성이 없어진다.다른 언어에서는 vptr을 만들 수 없기 때문이다. 추상 클래스로 만들고 싶지만 마땅히 만들..
항목 6. 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해버리자. 암시적 생성 함수의 문제컴파일러가 생성하는 함수는 모두 public 멤버가 된다.이처럼 의도하지 않은 인터페이스 노출은 실수를 유발할 수 있다. private 멤버로 명시적 선언만 하여 해결private 멤버로만 처리했을 때의 문제점해당 클래스의 멤버 함수 및 프랜드(friend) 함수 내에서 private 멤버를 호출할 여지가 있다.정의를 하지 않음으로써 호출 시 링크 시점에 에러가 뜨게 한다. 링크 시점 에러를 컴파일 시점 에러로 옮기는 방법 에러 탐지는 나중으로 미루는 것보다 미리하는 것이 좋기 때문.복사 생성자, 복사 대입 연산자를 private로 선언한 부모 클래스를 상속한다.컴파일러가 생성한 복사 함수..
항목 5. C++가 은근슬쩍 만들어 호출해버리는 함수들에 촉각을 세우자. 암시적 생성 생성자, 복사 생성자, 복사 대입 연산자, 소멸자 직접 선언하지 않으면 컴파일러가 저절로 선언해준다.암시적 생성 되는 복사 관련 함수들은 얕은 복사를 한다. 암시적으로 생성된 함수들의 특징기본 생성, 소멸자기본 클래스 및 비정적 데이터 멤버의 생성자, 소멸자를 호출해주는 등의 작업을 한다.즉, 컴파일러에게 “배후의 코드”를 깔 수 있는 자리를 마련해준다.상속한 기본 클래스의 소멸자가 가상 소멸자가 아니라면 비가상 소멸자로 만들어진다.복사 생성자, 복사 대입 연산자원본 객체의 비정적 데이터를 사본 객체 쪽으로 그냥 복사한다.복사 생성자와 복사 대입 연산자는 근본적으로 동작 원리가 같다.복사 대입 연산자를 priva..
항목 4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자 자동으로 하는 객체 초기화의 문제C++ 객체 초기화 규칙은 조금 복잡하다.그러므로 차라리 모든 객체를 사용하기 전에 초기화하는 것이 좋다. 초기화 시의 팁대입과 초기화를 헷갈리지 말자.대입 : 기본 생성자 호출 -> 복사 대입 연산자 호출초기화 리스트 사용 : 복사 생성자 호출 초기화란 생성자 본문이 실행되기 전에 되어야 하는 것이다.그러므로 멤버 초기화 리스트를 사용하자.클래스 멤버를 모두 초기화 리스트에 올리는 정책의 장점어떤 멤버가 초기화되지 않을 수 있다는 사실의 부담감이 없어진다.상수나 참조자 데이터 멤버는 대입이 불가능하다.즉, 반드시 초기화되어야 하므로 필수로 초기화 리스트에 넣어 주어야 한다. 객체를 구성하는 데이터의 ..