이 글에서는 C++에서 객체의 동적 할당(dynamic allocation)을 제한하는 방법에 대해 알아보겠습니다.
핵심 아이디어는 매우 간단합니다. new 연산자 함수를 클래스의 private 영역에 선언하면, 클래스 외부에서 new를 통해 객체를 동적으로 생성할 수 없게 됩니다. 그 결과 객체는 오직 스택(stack) 영역에만 생성될 수 있습니다.
예제 코드
#include <iostream>
using namespace std;
class Test {
// new 연산자를 private으로 선언
void* operator new(size_t size);
int x;
public:
Test() { x = 9; cout << "생성자가 호출되었습니다\n"; }
void display() { cout << "x = " << x << "\n"; }
~Test() { cout << "소멸자가 실행되었습니다\n"; }
};
int main() {
Test t; // 스택에 객체 생성 (정상 동작)
t.display();
return 0;
}
실행 결과
생성자가 호출되었습니다
x = 9
소멸자가 실행되었습니다
동작 원리
operator new가 private으로 선언되어 있기 때문에, 다음과 같이 힙(heap)에 객체를 생성하려는 코드는 컴파일 오류를 발생시킵니다.
Test* ptr = new Test(); // 컴파일 에러 발생!
컴파일러는 new Test() 표현식을 처리할 때 먼저 operator new를 호출해 메모리를 할당한 후 생성자를 호출하는데, 이 시점에 해당 멤버 함수에 대한 접근 권한이 없으므로 에러가 발생하는 것입니다.
참고: C++11의 = delete 활용
C++11 이상에서는 함수를 아예 삭제(deleted) 처리하여 의도를 더 명확하게 표현할 수 있습니다.
void* operator new(size_t size) = delete;
이 방식을 사용하면 컴파일러가 더 명확한 에러 메시지를 제공하며, 실수로 내부 멤버 함수에서 호출하는 경우도 방지할 수 있습니다.