다음은 가상 소멸자를 설명하기위한 예제입니다 (http://www.geeksforgeeks.org/g-fact-37/ 참조). 이 예제를 기반으로 코드를 수정하고 메모리 누수에 대해 질문합니다.가상 소멸자없이 기본 클래스 포인터를 삭제할 때 메모리 누수가 발생합니까?
기본 클래스의 변수가 int num이고 파생 클래스가 float money의 변수를 가지고 있다고 가정합니다.
delete base_ptr;
을 호출하면 기본 클래스의 소멸자가 가상이므로 ~derived()
을 먼저 호출 한 다음 ~Base()
을 호출해야합니다.
내 질문은 "삭제 기능을 할 수있다는 모두 INT의 납입 (기본 클래스)에 할당 된 메모리를 해제하고 돈 (파생 클래스)를 떠 것이다 그래야 똑똑?
내가 base_ptr 타입의 포인터라고 생각합니다 Base *이므로 Base 클래스에 필요한 메모리 양을 늘릴 수는 있지만 base_ptr이 Base 클래스의 유형을 가리키는 경우에도 int와 float가 모두 해제 된 것으로 보입니다. 누수가없는 경우 ~Base()
을 비가 상 destructor로 만들면 ~Base()
이 아닌 가상 소멸자를 사용하면 ~Derived()
이라는 호출이 누락됩니다. 기본 클래스와 파생 클래스 둘 다 "동적으로"할당되지 않으므로 ~Derived()
은 실제로 무료 전혀 메모리가없고 delete
의 기능은 int num
과 float money
의 메모리를 모두 비 웁니다.
#include <iostream>
using namespace std;
class Base {
public:
int num;
Base(int n):num(n){
cout<<"Base::Constructor\n";
}
virtual ~Base(){
cout<<"Base::Destructor\n";
}
};
class Derived : public Base {
private:
float money;
public:
Derived(int n, float m):Base(n),money(m){
cout<<"Derived::Constructor\n";
}
~Derived(){
cout<<"Derived::destructor\n";
}
};
int main() {
Base *base_ptr = new Derived(1,200.0);
delete base_ptr;
return 0;
}
Base 소멸자가 가상이 아닌 경우이 코드는 정의되지 않은 동작입니다. –
먼저 가상 소멸자가 없으면 코드에 정의되지 않은 동작이 발생하고 보이지 않는 유니콘의 색상에 대해 논쟁의 여지가 없습니다. 둘째, 프로그램이 "메모리의 일부만 비울지"를 묻기 전에'malloc'과'free'를 어떻게 사용하는지 생각해보고 할당 해제 할 메모리의 양을'free'라고 어떻게 생각하는지 물어보십시오 . –
C++ 표준은 기본 클래스 포인터를 통해 파생 클래스 인스턴스를 삭제하면 정의되지 않은 동작임을 명시 적으로 명시합니다. 당신이 "시스템을 속일 수있는"때를 알아내는 것은 가치가있는 것 같지 않습니다. – PaulMcKenzie