C++에서 새로운 객체를 생성하려면 먼저 메모리에 메모리 블록을 할당한 뒤, 생성자를 호출하여 해당 메모리를 초기화해야 합니다. 이 과정에서 new 키워드를 사용하면 두 가지 작업이 한 번에 처리되지만, operator new는 단순히 메모리 공간만 할당한다는 중요한 차이가 있습니다.
new 키워드란?
new 연산자는 힙(heap) 영역에 대한 메모리 할당을 요청하는 특수한 연산자입니다. 충분한 메모리가 확보된 경우에만 new 연산자가 해당 메모리를 포인터 변수에 연결하고 초기화합니다. 일반적인 new 키워드로 객체를 생성하면 다음 두 가지 작업이 순차적으로 수행됩니다.
- 객체를 위한 메모리 블록을 힙 영역에 할당
- 생성자를 호출하여 메모리 블록 초기화
예제 코드
#include <iostream>
using namespace std;
class Box {
public:
Box() {
cout << "Constructor called!" << endl;
}
};
int main() {
Box* myBox = new Box;
}
실행 결과
Constructor called!
위 코드에서 new 키워드가 사용되자 메모리 할당과 함께 생성자가 자동으로 호출되어 "Constructor called!"가 출력된 것을 확인할 수 있습니다.
operator new란?
operator new는 하나의 함수로, new 연산자를 오버로드(overload)하는 데 사용됩니다. 이 함수를 활용하면 원시(raw) 메모리 블록을 직접 할당할 수 있으며, 개념적으로 C 언어의 malloc()이나 calloc() 함수와 유사합니다.
중요한 점은 operator new는 생성자를 호출하지 않는다는 것입니다. 따라서 이 함수가 반환하는 메모리는 초기화되지 않은 상태입니다. 다만, 오버로드된 operator new가 포인터를 반환한 이후에 컴파일러가 자동으로 생성자를 호출하여 객체를 초기화합니다.
예제 코드
#include <iostream>
#include <cstdlib>
using namespace std;
class Box {
public:
Box() {
cout << "Constructor called!" << endl;
}
void *operator new(size_t size) {
cout << "Call Operator New" << endl;
void *p = malloc(size);
return p;
}
};
int main() {
Box* myBox = new Box;
}
실행 결과
Call Operator New
Constructor called!
실행 결과를 보면 오버로드된 operator new가 먼저 호출되어 메모리를 할당한 뒤, 그다음 생성자가 호출되어 객체가 초기화되는 순서를 확인할 수 있습니다.
핵심 차이점 비교
| 구분 | new 키워드 | operator new |
|---|---|---|
| 역할 | 메모리 할당 + 생성자 호출 | 메모리 할당만 수행 |
| 종류 | 연산자(operator) | 오버로드 가능한 함수 |
| 유사 기능 | 없음 | malloc(), calloc() |
| 초기화 여부 | 생성자를 통해 초기화됨 | 단독 사용 시 초기화되지 않음 |
정리하면, new 키워드는 내부적으로 operator new를 통해 메모리를 할당받은 후 생성자를 호출하는 상위 개념이며, operator new는 그 하위 단계에서 실제 메모리 할당만 담당하는 함수라고 이해하면 됩니다.