C++의 가상 소멸자

C Ui Gasang Somyeolja



C++은 프로그래밍의 기본 개념에 대한 기초를 제공하고 프로그래머의 논리적 사고를 강화하는 데 사용되는 언어입니다. C++에서 OOP는 클래스의 객체를 생성하는 객체 지향 언어이기 때문에 OOP가 중요한 역할을 합니다. OOP에서는 클래스와 객체를 연구합니다. 클래스에는 다른 유형 및 다른 멤버 함수의 변수인 데이터 멤버가 포함됩니다. 인스턴스의 도움으로 모든 클래스의 데이터에 액세스합니다. 클래스를 만들 때 모든 클래스에는 생성자와 소멸자가 있습니다. 생성자는 해당 클래스의 객체가 생성될 때 자체적으로 호출됩니다. 생성자 내에서 클래스의 변수를 초기화할 수도 있습니다. 소멸자도 생성자와 함께 자동으로 생성되지만 소멸자는 개체를 파괴하며 개체를 파괴하기 전에 호출되는 마지막 함수입니다. 예를 들어 'Profession' 클래스와 같은 클래스 이름이 생성됩니다. 생성자는 Profession()이고 소멸자는 ~Profession()입니다. 세 사람의 이름은 같다.

OOP, 생성자 및 소멸자에 대해 이야기한 후에 이제 가상 소멸자에 대해 이야기하겠습니다. 가상 소멸자는 이름에서 알 수 있듯이 객체를 파괴합니다. 기본 클래스와 기본 클래스에서 파생된 파생 클래스가 있습니다. 두 클래스 모두 생성자와 소멸자가 있습니다. 가상 소멸자는 “virtual” 키워드와 함께 기본 클래스 포인터를 사용하여 파생 클래스의 객체를 삭제하면서 파생 클래스 객체를 통해 할당된 메모리를 해제합니다.

가상 소멸자를 사용하는 이유는 무엇입니까?

클래스 멤버 함수의 실행이 완료되거나 main() 메서드의 실행이 끝나려고 하면 객체 생성 중에 할당된 메모리를 해제하기 위해 소멸자가 자동으로 호출됩니다. 이제 가상 소멸자를 사용하는 이유는 무엇입니까? 파생 클래스를 가리키는 기본 클래스가 삭제되면 여기에서 포인터(*)가 사용됩니다. 기본 클래스 소멸자는 이 프로세스 중에만 호출됩니다. 파생 클래스 소멸자가 호출되지 않아 문제가 발생합니다. 그중 하나는 메모리 누수 문제입니다. 이 문제를 방지하고 코드 보안을 유지하기 위해 기본 클래스 소멸자를 삭제하여 객체를 생성하는 동안 할당된 메모리 공간을 확보하기 위해 객체를 가상으로 파괴합니다.

가상 소멸자가 없는 C++ 기본 예제

포인터를 삭제하는 간단한 프로그램으로 프로그램이 가상 소멸자 없이 어떻게 작동하는지 봅시다.

암호:

#include

네임스페이스 표준 사용 ;
클래스 부모_클래스0
{
공공의 :
부모_클래스0 ( )
{ 쿠우트 << '부모 클래스 생성자' << ; }
~Parent_Class0 ( )
{ 쿠우트 << '부모 클래스 소멸자' << ; }
} ;
클래스 Child_1 : 공개 Parent_Class0
{
공공의 :
아동_1 ( )
{ 쿠우트 << '자식 클래스 생성자' << ; }
~Child_1 ( )
{ 쿠우트 << '자식 클래스 소멸자' << ; }
} ;
정수 기본 ( )
{
부모_클래스0 * 바늘 = 새로운 Child_1 ( ) ;
포인터 삭제 ;
반품 0 ;
}

이 코드는 가상 소멸자 없이 코드가 실행되는 방식을 설명합니다. 먼저 부모 클래스가 될 'Parent_Class0'이라는 클래스를 만듭니다. 이 클래스 내에서 생성자와 소멸자를 만듭니다. 아시다시피 생성자와 소멸자의 이름은 클래스와 동일합니다. 소멸자는 생성자와 유사하게 표현되지만 생성자와 구별되는 기호(~)가 있습니다. 생성자와 소멸자 내부에서 'cout<<'를 사용하여 메시지를 인쇄합니다. 이제 'Child_1'이라는 또 다른 클래스를 만듭니다. 이 클래스는 상위 클래스 'Parent_Class0'에서 파생됩니다. 파생 클래스에는 출력 화면에 인쇄할 메시지가 포함된 생성자와 소멸자가 있습니다.

main() 메서드에서 'Parent_Class0'의 인스턴스를 만들고 여기에 파생 클래스를 할당합니다. 이 경우 기억해야 할 중요한 점은 포인터를 사용하여 부모 클래스를 검색한다는 것입니다. 부모 클래스 내부로 들어가면 부모 클래스 생성자를 실행합니다. 그런 다음 자식 클래스로 이동하여 해당 생성자를 실행합니다. 자식 클래스의 소멸자를 실행하기 전에 부모 클래스의 소멸자를 실행해야 합니다. 컴파일러는 부모 클래스의 소멸자를 실행하고 자식 클래스의 소멸자를 실행하지 않고 클래스를 종료합니다. 그게 문제 야; 자식 클래스의 메모리를 해제하지 않습니다. 부모 클래스의 생성자, 자식 클래스의 생성자 및 부모 클래스의 소멸자를 나타냅니다. 이는 하위 클래스의 소멸자가 실행되지 않음을 보여줍니다. 이 실행 후 main() 함수에서 포인터를 삭제합니다.

산출:

가상 소멸자를 사용한 C++ 예제

가상 소멸자가 있을 때와 없을 때 작동 방식을 구별하기 위해 간단한 코드로 가상 소멸자에 대해 논의해 보겠습니다.

암호:

#include

네임스페이스 표준 사용 ;
클래스 부모_클래스0
{
공공의 :
부모_클래스0 ( )
{ 쿠우트 << '부모 클래스 생성자' << ; }
가상 ~Parent_Class0 ( )
{ 쿠우트 << '부모 클래스 소멸자' << ; }
} ;
클래스 Child_1 : 공개 Parent_Class0
{
공공의 :
아동_1 ( )
{ 쿠우트 << '자식 클래스 생성자' << ; }
가상 ~Child_1 ( )
{ 쿠우트 << '자식 클래스 소멸자' << ; }
} ;
정수 기본 ( )
{
부모_클래스0 * 바늘 = 새로운 Child_1 ( ) ;
포인터 삭제 ;
반품 0 ;
}

첫 번째 프로그램은 가상 소멸자 없이 우리가 직면하고 있는 문제를 설명했습니다. 이제 이 코드는 가상 소멸자를 사용하여 해당 문제를 해결합니다. 먼저 첫 번째 코드를 복사하고 이 프로그램의 두 위치에 하나의 키워드만 추가합니다. 그 단어는 '가상'입니다. 부모 클래스 'Parent_Class0'의 소멸자와 함께 이 단어를 삽입합니다. 마찬가지로 부모 클래스에서 파생된 'Child_1'인 자식 클래스의 소멸자로 이를 언급합니다. 이 '가상' 키워드는 약간의 변경을 가하며 'Child_1' 자식 클래스의 소멸자를 먼저 실행합니다. 그런 다음 부모 클래스 'Parent_Class0'의 소멸자를 실행합니다. 프로그램의 나머지 부분은 가상 소멸자 없이 작동하는 것과 동일하게 작동합니다. 이 작은 코드 조각을 추가하면 메모리 누수로부터 메모리를 절약할 수 있습니다. 이제 콘솔에 4개의 메시지가 표시됩니다. 먼저 부모 클래스의 생성자, 자식 클래스의 생성자, 자식 클래스의 소멸자, 부모 클래스의 소멸자입니다. 결국 main() 메서드 내에서 포인터를 삭제합니다.

산출:

순수 가상 소멸자의 C++ 예

이 코드에서는 순수한 가상 소멸자, 작동 방식 및 가상 소멸자와 다른 점에 대해 설명합니다.

암호:

#include

클래스 Parent_0 {
공공의 :
가상 ~Parent_0 ( ) = 0 ;
} ;
부모_0 :: ~Parent_0 ( )
{
성병 :: 쿠우트 << '안녕하세요 저는 Pure Destructor입니다. 저를 부르셨습니다!' ;
}
클래스 Child_0 : 공개 Parent_0 {
공공의 :
~Child_0 ( ) { 성병 :: 쿠우트 << '파생 소멸자가 여기에 있습니다. \N ' ; }
} ;

정수 기본 ( )
{
부모_0 * ptr_0 = 새로운 아동_0 ( ) ;
삭제 ptr_0 ;
반품 0 ;
}

코드의 첫 번째 단계에서 상위 클래스 'Parent_0'이 생성됩니다. 그 안에 가상 부모 소멸자를 만들고 0으로 할당합니다. 이것은 가상 소멸자를 순수 가상 소멸자로 설정합니다. 즉, 부모 클래스는 이제 추상적이며 이 클래스의 인스턴스를 만들 수 없습니다. 부모 클래스 'Parent_0' 외부에서 소멸자와 std::cout을 정의합니다. 필요한 텍스트는 std::cout을 활용하여 표시됩니다. 그런 다음 부모 클래스에서 'Child_0' 클래스를 파생시키고 해당 소멸자를 정의합니다. 소멸자 내부에 메시지를 인쇄합니다. main() 함수에서 부모 클래스의 포인터를 만들고 여기에 자식 클래스를 할당합니다.

컴파일러는 부모 클래스 'Parent_0'으로 이동합니다. 포인터가 생성되면 해당 생성자가 자동으로 호출됩니다. 그런 다음 컴파일러는 하위 클래스로 이동하여 해당 생성자를 호출합니다. 생성자가 성공적으로 실행되면 자식 클래스 “Child_0”의 소멸자를 실행합니다. 그런 다음 부모 클래스의 소멸자를 실행합니다. 이렇게 하면 순수한 가상 소멸자를 만들 수 있습니다. 이 메서드를 사용하면 부모 클래스가 추상화되어 쓸모없게 되므로 사용하지 않는 것이 좋습니다. 주로 사용되는 방법론은 가상 소멸자이며 이는 좋은 사례입니다.

산출:

결론

우리는 가상 소멸자에 대해 OOP의 개념에서 시작하여 생성자와 소멸자로 이동하는 방법을 배웠습니다. 이 모든 것을 설명한 후 코딩 예제와 순수 가상 소멸자를 통해 가상 소멸자에 대해 자세히 논의했습니다. 가상 소멸자를 설명하기 전에 생성자, 소멸자 및 상속에 대해 알아야 합니다. 상속에서는 부모 클래스에서 클래스를 상속합니다. 하위 클래스는 둘 이상일 수 있지만 상위 클래스는 하나뿐입니다. 가상 소멸자와 순수 가상 소멸자는 메모리 누수를 방지하기 위해 상속에 적용됩니다. 기본 예제부터 고급 예제까지 파생 클래스의 메모리를 사용하고 가상으로 파괴하기 위해 알아야 할 모든 것을 다루었습니다.