개발/C, C++

[C++]new, delete 연산자 오버로딩

huiyu 2019. 1. 13. 09:35

 new 연산자 오버로딩

Point * ptr = new Point(3, 4);

기본적으로 제공되는 new 연산자가 하는 일

 1) 메모리 공간의 할당
 2) 생성자의 호출
 3) 할당하고자 하는 자료형에 맞게 반환된 주소 값의 형 변환

* 이중 3)번의 일을 수행함으로써 C에서 사용하던 malloc과 달리 new 연산자가 반환하는 주소값을 형변환할필요가 없게 된다.

 기본적으로 제공되는 new 연산자가 하는 일은 위 3가지이고, 우리가 new 연산자를 오버로딩할 경우엔 위 세가지 작업중 1번에 해당하는 메모리 공간의 할당만 구현하면 된다.


*new 연산자 오버로딩은 아래와 같이 오버로딩 하도록 되어있다.

 - 반드시 void 포인터 형 반환
 - 매개변수형은 size_t

 Point * ptr = new Point(3,4);

위와 같은 코드를 만나면, 먼저 필요한 메모리 공간을 계산한다. 그리고 크 크기를 operator new 함수를 호출하면서 인자로 전달한다.(바이트 단위)

따라서 우리는 아래와 같은 형태로 operator new 함수를 정의해야 한다.

1
2
3
4
5
void * operator new (size_t size)
{
  void * adr = new char[size];
  return adr;
}
cs

 -> operator new함수를 통해 할당한 메모리 공간의 주소값을 반환하면, 컴파일러는 2)생성자를 호출해서 메모리 공간을 대상으로 초기화를 진행한다. 다음 완성된 객체의 주소 값을 Point 클래스의 3)포인터 형으로 형변환을 한 다음 반환한다.


 delete 연산자 오버로딩

 delete ptr;

-> 컴파일러는 먼저 ptr이 가리키는 객체의 소멸자를 호출한다. 그리고는 다음의 형태로 정의된 함수에 ptr에 저장된 주소값을 전달한다.

1
2
3
4
void operator delete (void * adr)
{
  delete []adr;
}
cs

소멸자는 오버로딩 된 함수가 호출되기 전에 호출되니 오버로딩 된 함수에서는 메모리 공간의 소멸을 책임져야 한다.


** 객체생성이 완성된 상태가 아닌데, operator new, operator delete의 오버로딩된 멤버함수가 호출될 수 있는 이유?
 - operator new와 operator delete 함수는 static함수로 간주한다. 그러기 때문에 객체 생성과정에서 호출이 가능했다.


 operator new & operator new [ ]

 new 연산자는 다음 두가지 형태로 오버로딩이 가능하다.

    void * operator new ( size_t size )

    void * operator new[] (size_t size )

첫번째 함수는 위에서 설명한 기본적인 operator new 함수의 모습이며, 
두번째 함수는 new 연산자를 이용한 배열할당 시 호출되는 함수이다.

 Point * arr = new Point[3];

컴파일러는 세 개의 Point객체에 필요한 메모리 공간을 바이트 단위로 계산해서 이를 인자로 전달하며 operator new[]함수를 호출한다.


delete 연산자도 다음 두가지 형태로 오버로딩이 가능하다.

   void operator delete (void * adr) { .... }

   void operator delete [] (void * adr) { .... }

첫번째 역시 기본적인 operator delete 의 모습이며, 두번째는 delete 연산자를 이용한 배열 소멸시 호출되는 함수이다.

 delete []arr;

컴파일러는 소멸자를 호출한 이후에 arr에 저장된 주소값을 전달하면서 operator delete[]함수를 호출한다.


[참고자료]
윤성우 열혈 C++ 프로그래밍 11-3 그 이외의 연산자 오버로딩
  - new 연산자 오버로딩에 대한 상세한 이해
  - delete 연산자 오버로딩에 대한 상세한 이해와 예제
  - operator new & operator new[]

728x90
반응형