new와 delete도 연산자이기 때무에 오버로딩이 가능하다. 그래서 이 두 연산자의 오버로딩에 대해서 예를 보이겠다. 또한 포인터 연산자를 오버로딩 하면서 개념적으로 어렵다고 이야기하는 ‘스마트 포인터 ‘와 ‘펑터(functor)’에 대해서도 간단히 설명하겠다.

new 연산자 오버로딩에 대한 상세한 이해

new 연산자가 하는 일은 다음과 같다:

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

우리는 위에 과정중 1번만 할수 있고 나머지 2, 3번은 오버로딩 할수 있는 대상도 아니다.

new 연산자는 다음과 같이 오버로딩 해야한다고 약속되어 있다:

void *operator new (size_t size) {…}
void *operator new(size_t size)
{
	void *adr=new char[size];
	return adr;
}

new 연산자가 반환하는 값은 operator new 함수가 반환하는 값이 아니다. operator new 함수가 반환하는 값은, 컴파일러에 의해 적절히 형 변환이 된 값이다. 또한 생성자의 호출정보는 operator new 함수와 아무런 상관이 없다. 생성자의 호출은 여전히 컴파일러의 몫이기 땜누에 이 정보는 컴파일러에 의해서 참조될 뿐이다.

“new 연산자가 멤버함수의 형태로 오버로딩 되었다면, 객체가 생성된 이후에 호출이 되어야 하잖아! 근데 new 연산자는 객체를 생성할 때 사용하는 연산자란 말이야!”

delete 연산자 오버로딩에 대한 상세한 이해와 예제

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

다음의 문자응로 객체의 소멸을 명령하면

delete ptr;

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

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

참고로, 사용하는 컴파일러에서 void 포인터 형 대상의 delete 연산을 허용하지 않는다면, 위의 delete 문을 다음과 같이 작성하면 된다.

delete []((char*)adr);