3법칙은 예외 세이프코드를 빌드하기 위한 경험 법칙에 따른 C++의 규칙 중 하나입니다. 이 규칙은 예외 없는 연습을 위해 클래스의 기본 멤버를 사용하는 방법을 규정합니다.
3의 법칙은 Big Three 또는 Big Three의 법칙이라고도 하며 클래스에 대해 규정합니다. 클래스가 언급된 세 가지 중 하나를 정의하는 경우 세 가지 모두를 명시적으로 정의해야 합니다.
- 소멸자
- 복사 생성자
- 할당 생성자 복사
이 세 가지는 클래스의 특별한 멤버 함수입니다. 프로그래머가 명시적으로 정의하지 않은 경우 컴파일러는 암시적 버전을 제공합니다. 위의 항목 중 하나가 명시적으로 정의된 경우 다른 두 가지에 대한 암시적 버전은 부적절하고 재정의해야 함을 의미합니다.
이것은 암시적으로 생성된 생성자와 할당 연산자의 데이터 멤버의 얕은 복사 때문에 발생합니다. 클래스에 동적으로 할당된 리소스를 가리키는 포인터가 포함된 경우 전체 복사가 필요합니다.
기본 소멸자는 사용하지 않는 개체를 제거합니다. 복사 생성자가 정의되지 않은 경우 소멸자는 복사본을 포함하는 개체에 대해 한 번, 데이터 멤버가 복사되는 개체에 대해 두 번 실행됩니다. 이를 피하기 위해서는 명시적 정의가 필요합니다.
복사 생성자와 복사 할당 연산자가 없지만 소멸자가 존재하는 예를 들어 이해합시다 -
예
#include <stdio.h> class Numbers{ private: int num; int* ptr; public: Numbers( int n, int* p ) //copy constructor{ num =n ; ptr = new int[ num ]; } ~Numbers() //destructor{ delete ptr; ptr = NULL; } }; int main(){ int arr[ 4 ] = { 11, 22, 33, 44 }; Numbers Num1( 4, arr ); // this creates problem Numbers Num2( Num1 ); return 0; }
출력
*** Error in `./a.out': double free or corruption (fasttop): 0x0000000001f46c20 *** Aborted
-
이것은 프로그램이 범위를 벗어날 때 소멸자가 두 번 호출되기 때문에 발생했습니다. 먼저 Num1을 삭제한 다음 Num2를 삭제합니다. 기본 복사 생성자는 포인터 ptr의 복사본을 생성하지만 할당된 메모리는 생성하지 않습니다. 따라서 Num1이 제거되면 후속 ptr은 프로그램을 충돌시킵니다.