항목 52 placement new를 작성한다면 placement delete도 작성하자
52.1 placement new
■ 52.1.1 placement new
- placement new란 다른 매개변수를 추가로 전달하는 operator new 함수를 말한다.
- <new> 헤더 파일을 포함하면 void* 포인터를 추가로 받는 표준 placement new를 사용할 수 있다.
// 어떤 객체를 생성할 메모리 위치를 나타내는 포인터를 매개변수로 받는 placement new입니다.
// C++ 표준 라이브러리에 정의되어 있습니다.
void* operator new(std::size_t _iSize, void* _pMemory) throw();
■ 52.1.2 placement new 예외 처리
// 기본 operator new
void* operator new(std::size_t _iSize) throw(std::bad_alloc);
// 기본 operator delete는 기본 operator new에 대응됩니다.
void* operator delete(void* _pMemory) throw();
class Widget
{
public:
// 비표준 placement new
static void* operator new(std::size_t _iSize, std::ostream& _osLog) throw(std::bad_alloc);
// 비표준 placement delete는 비표준 placement new에 대응하도록 작성합니다.
static void operator delete(void* _pMemory, std::ostream& _osLog) throw();
};
// 기본 operator new로 할당합니다.
Widget* pWidget = new Widget;
// placement new로 할당합니다.
Widget* pWidget = new (std::cerr) Widget;
- new 표현식을 작성하면 operator new 함수와 Widget 생성자가 호출된다.
- Widget 생성자에서 예외가 발생하는 경우, operator new로 할당한 메모리는 (사용자가 아닌) 런타임 시스템에서 해제해야 한다.
- 이때, 런타임 시스템은 operator new 함수에 대응되는, 즉 전달받는 매개변수 개수와 타입이 같은 operator delete 함수를 호출한다.
- 그러한 operator delete가 없는 경우, 어떠한 operator delete도 호출하지 않는다.
- 따라서 placement new를 작성한다면 메모리가 누수되지 않도록 placement delete를 마련해야 한다.
- Widget 생성자에서 예외가 발생하지 않는 경우, operator new로 할당한 메모리는 기본 operator delete로 해제한다.
- 따라서 placement new를 작성한다면 기본 operator delete도 마련해야 한다.
52.2 operator new 유효 범위
- 클래스에 정의한 operator new가 전역 operator new를 가리지 않도록 주의해야 한다.
- 기본 클래스에 정의된 operator new는 전역 operator new를 가린다.
- 자식 클래스에 정의된 operator new는 전역 operator new와 기본 클래스 operator new도 가린다.
// 전역 operator new들
// 기본 operator new
void* operator new(std::size_t) throw(std::bad_alloc);
// placement new
void* operator new(std::size_t, void*) throw();
// nothrow new
void* operator new(std::size_t, const std::nothrow_t&) throw();
NOTE
① placement new를 만들 때, 이 함수와 짝 맞는 placement delete를 만들자.
② placement new, placement delete 함수를 선언할 때, 표준 operator new, operator delete가 가려지지 않도록 주의하자.
'Object Oriented Programming(C++) > Effective C++' 카테고리의 다른 글
Effective C++ | 항목 43 템플릿으로 만들어진 부모 클래스 안의 이름에 접근하는 방법을 알아두자 (0) | 2024.08.06 |
---|---|
Effective C++ | 항목 42 typename의 두 가지 의미를 제대로 파악하자 (0) | 2024.08.06 |
Effective C++ | 항목 41 템플릿 프로그래밍은 암시적 인터페이스와 컴파일 시간 다형성부터 (0) | 2024.08.06 |
Effective C++ | 항목 40 다중 상속은 심사숙고해서 사용하자 (0) | 2024.08.06 |
Effective C++ | 항목 39 private 상속은 심사숙고해서 구사하자 (0) | 2024.08.06 |
댓글