가상 소멸자
C++에서는 생성자를 가상의 생성자로 정의할 수 없다. 왜냐하면 생성자는 객체가 인스턴스화될 때만 호출되고 가상 함수의 구현은 실제로 가상 함수 테이블 포인터를 통해 호출되며 객체 업데이트가 없기 때문이다. 물론 메모리 공간 없이는 호출할 수 없으므로 객체를 인스턴스화하기 전의 가상 생성자는 의미가 없으며 구현할 수도 없습니다.
그러나 소멸자는 가상 함수일 수 있으며 대부분의 경우 가상 소멸자로 선언됩니다. 이런 방식으로 기본 클래스 포인터가 가리키는 파생 클래스의 객체가 해제되면 하위 클래스의 소멸자가 가리키는 실제 객체 유형에 따라 동적으로 컴파일 및 호출되어 올바른 객체 메모리 해제를 달성할 수 있습니다. .
아래에서 실험을 해보겠습니다. 코드를 살펴보세요.
/************************************//Des: C++ 튜토리얼 데모//저자: Huang/ /저작권:www.dotcpp.com//날짜:2017/12/27************************************ * *******/#include<iostream>usingnamespacestd;classPoint{private:intx,y;int*str;public:Point(intx=0,inty=0){this->x=x;this- > y=y;str=newint[100];}~Point(){delete[]str;cout<<CalledPoint'sDestructorandDeletedstr!<<endl;}};classCircle:publicPoint{private:intr;int*str;public : Circle(intx,inty,intR):Point(x,y){r=R;str=newint[100];}~Circle(){delete[]str;cout<<CalledCircle'sDestructorandDeletedstr!<<endl; } };intmain(){Point*p;p=newCircle(10,10,20);deletep;return0;}
코드를 보면 기본 클래스에 virtual 로 선언된 소멸자가 없고 기본 클래스와 파생 클래스 모두 동적 메모리 할당을 갖고 있습니다. 그런 다음 동적으로 메모리를 할당하여 Circle 클래스를 생성한 다음 삭제합니다. 실행 후 스크린샷은 다음과 같습니다.
기본 클래스의 소멸자만 호출되므로 파생 클래스에 4*100바이트의 새 메모리가 남게 되어 메모리 누수가 발생하는 것을 명확하게 알 수 있습니다!
그리고 기본 클래스의 소멸자가 가상으로 선언되면 결과는 매우 달라집니다! 이때 다형성 효과는 먼저 파생 클래스의 공간을 해제한 다음 기본 클래스의 메모리 공간을 해제합니다. 아래와 같이 완벽하게 종료됩니다.
이상, 가상 소멸자가 가져오는 이점은 직접 체험해 볼 수 있습니다.