[C/C++] Rule

할랑말랑·2026년 3월 11일

C/C++

목록 보기
18/45

Rule

C++에서 종종 클래스는 동적으로 할당된 메모리, 파일 핸들, 네트워크 소켓, 뮤텍스 등 리소스를 관리한다. 클래스가 이러한 리로스를 직접 소유하고 관리할 때, 객체의 생성, 복사, 이동, 소멸 시에 이 리소스를 올바르게 처리해야한다. 그렇지 않으면 메모리 누수, 이중 해제, 댕글링 포인터 같은 심각한 버그가 발생한다.
이를 위해 컴파일러는 필요에 따라 특별한 멤버 함수를 자동으로 생성해준다.

  • 소멸자(Destructor)
  • 복사 생성자(Copy Constructor)
  • 복사 대입 연산자(Copy Assignment Operator)
  • 이동 생성자(Move Constructor) C++11
  • 이동 대입 연산자(Move Assignment Operator) C++11

"Rule of X" 법칙들은 바로 이 특별한 멤버 함수들을 언제, 어떻게 직접 구현해야 하는지에 대한 지침이다.

1. Rule of Three(3의 법칙)

클래스에서 소멸자, 복사 생성자, 복사 대입 연산자 중 하나라도 직접 정의해야 한다면, 세 가지의 모두를 정의해야 한다는 규칙

멤버 변수 포인터를 보유한 객체에게 있어 디폴트 복사 연산자는 위험요소가 존재한다. 메모리 누수, 댕글링 포인터 등

디폴트 연산자로 인한 얕은 복사를 방지하기 위해 복사생성자, 복사 대입자를 오버로딩하여 깊은 복사가 발생하도록 해주어야 메모리를 안전하게 관리할 수 있게 된다.

Rule Of Three는 이를 확고히 하기 위한 규칙이다. 포인터 변수를 보유한 객체라면 복사 생성자, 복사 대입자, 소멸자 3가지의 연산자를 반드시 오버로딩하여 올바르게 구현하라는 규칙이 Rule Of Three이다.

2. Rule of Five(5의 법칙)

Rule of Three의 확장판이다.(이동 생성자,이동 대입 연산자를 포함)

C++11 에서는 이동 시멘틱스(Move Semantics)가 도입되었다. 이는 임시 객체(rvalue)를 복사 대신 소유권을 가져오는 효율적인 방법이다.

사용자가 복사생성자,대입 연산자,소멸자 중 하나라도 직접 정의하면, 컴파일러는 더 이상 이동 생성자와 이동 대입 연산자를 자동으로 생성해주지 않는다.
이는 안전을 위한 조치이지만, 성능 저하를 유발할 수 있다.

결론은 리소스를 직접 관리하는 클래스를 작성한다면 특수 멤버 함수를 전부 명시적으로 구현하여 정확성과 성능을 모두 잡아야한다.

3. Rule of Zero(0의 법칙)

클래스를 설계할 때는 특수 멤버 함수를 명시적으로 정의하지 않도록 해야 한다.

가장 권장되는 현대 C++의 접근 방식이다.

특수 멤버 함수를 사용하는 대신 스마트 포인터나 STL 컨테이너를 사용하여 RAII패턴을 활용하면 컴파일러가 자동으로 생성하는 특수 멤버 함수들이 정확히 이 동작을 수행해준다.

RAII (Resource Acquisition is initialization)

자원의 안전한 사용을 위해 객체가 쓰이는 스코프를 벗어나면 자원을 해제해주는 패턴

객체가 생성될 때(초기화될 때), 생성자(Constructor)에서 리소스를 획득합니다.

C++에서는 객체가 자신의 스코프(scope, { } 블록)를 벗어날 때 소멸자가 자동으로, 그리고 무조건 호출되는 것을 언어 차원에서 보장합니다. RAII는 바로 이 강력한 보장을 활용하는 것입니다.

0개의 댓글