C++/Effective C++ (6) 썸네일형 리스트형 항목 17: new 로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자 자원 누출 가능성 스마트 포인터 생성 코드 처리 우선순위를 알려주는 함수와 동적으로 할당한 Widget 객체에 대해 우선순위에 따라 처리를 적용하는 함수가 있다고 하자 int priority(); void processWidget(std::shard_ptr pw, int priority); //shared_ptr 을 통해 자원관리호출시 아래와 같이 쓰면 컴파일 에러가 난다! processWidget(new Widget, priority());shared_ptr 의 생성자는 explicit 로 선언되어 있기 때문에, new Widget 에 의해 만들어진 포인터가 shared_ptr 타입의 객체로 바뀌는 암시적 변환은 일어나지 않는다. 그래서 아래와 같이 써줘야 한다. processWidget(shared_.. 항목 16: new 및 delete 를 사용할 때는 형태를 반드시 맞추자 delete 사용시 주의 사항 아래 코드를 보고 문제점을 찾아보자. string *stringArray = new string[100]; delete stringArray;그렇다. new 는 배열을 할당했는데, delete 는 그렇지 않다. stringArray 가 가리키는 100 개의 string 객체중 99개는 정상적인 소멸과정을 거치지 못할 가능성이 크다. new 와 delete 연산자의 동작 new 연산자를 사용해 어떤 객체를 동적 할당하게 되면, 두 가지의 내부 동작이 이뤄진다. 1) 메모리가 할당된다. (operator new 라는 이름의 함수가 쓰인다. 항목 49. 51 참조) 2) 할당된 메모리에 대해 한 개 이상의 생성자가 호출된다. delete 연산자를 쓸 때는 다음과 같은 두 가지 내.. 항목 15: 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자 자원 관리 클래스의 자원 접근 자원에 접근하려 하는 예 아래 createInvestment 로 자원을 만든 후, pInv 에 넘겨주는 경우를 생각해보자 (항목 13 예제) shared_ptr pInv(createInvestment());그리고 Investment 객체를 사용하는 함수가 다음과 같이 정의 되어있다고 하자 int daysHeld(const Investment *p); //그러면 이렇게 호출하고 싶겠죠 int days = daysHeld(pInv); 그러나 위와 같이 할 경우 컴파일이 되지 않는다. daysHeld 는 Investment * 타입의 포인터를 원하는데 , shared_ptr 타입을 넘기고 있으니 안되는 것! RAII 클래스 객체의 자원 변환 위 문제를 해결하기 위해서는 결국 RA.. 항목 14: 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자 자원 관리 클래스에 대한 고찰 항목 13에서 처럼 힙 기반 자원이 아니라면 어떻게 관리해야 하는가? 자원 관리 클래스를 결국 만들어야 한다. 예를 들어 Mutex 타입의 객체를 조작하는 C API 를 사용중이라고 가정해보자. 해당 API 는 lock, unlock 함수를 제공한다. void lock(Mutex *pm); void unlock(Mutext *pm);이전에 걸어 놓은 뮤텍스 잠금을 잊지 않고 풀어주기 위한 용도의 잠금 관리 클래스를 만들고 싶다면 이 클래스는 RAII 법칙을 따라 구성한다. == 생성 시에 자원을 획득, 소멸 시에 자원을 해제! 잠금 관리 클래스 class Lock { public: explicit Lock(Mutext *pm) : mutexPtr(pm){ lock(mutex.. 항목 13: 자원 관리에는 객체가 그만! 참고 : 책에서는 auto_ptr 을 예로 들어서 계속 설명하지만, auto_ptr 은 사용권장 되고 있지 않기 때문에 관련한 부분은 여기에 적지 않았다. 스마트 포인터 동적 할당한 객체의 문제 아래와 같이 동적할당한 객체를 얻어내고, 해당 객체를 사용한 뒤에 delete 해주는 함수가 있다하자. void f() { Investment *pInv = createInvestment(); ... delete pInv; }이 경우 해당 객체를 삭제 하지 못하는 경우가 발생할 수 있다. 1) delete 이전에 함수가 리턴되는 상황 2) 도중에 예외가 던져져서 delete를 하지 못하는 상황 createInvestment 로 얻어낸 자원이 항상 해제되도록 하는 방법은, 자원을 객체에 넣고 그 자원을 소멸자가 맡.. 항목 31 : 파일사이의 컴파일 의존성을 줄이자 인터페이스와 구현의 분리 c++ 의 class definiton 는 클래스 인터페이스 + 구현 세부사항까지 지정 할 수 있어서 c++ 은 인터페이스와 구현을 깔끔하게 분리하기 힘들다. 예를 들어 아래 코드처럼 Person 구현의 세부사항에 속하는 Date, Address 정의된 정보를 가져오기 위해 "date.h", "address.h" 들을 물어와야 한다. #include #include "date.h" #include "address.h" class Person { public: Person(const Date& birthday, const Address& addr); private : std::string name; Date theBirthDate; //구현 세부사항 Address theAddres.. 이전 1 다음