가상 소멸자(Virtual Destructor)
Programming/C++ 2012. 8. 20. 00:55 |가상함수 말고도 virtual 키워드를 붙여줘야 할 대상이 하나 더 있다. 그건 바로 "소멸자" 이다. 즉, virtual 선언은 소멸자에도 올 수 있다.
#include <iostream>
#include <cstring>
using namespace std;
class First
{
private:
char* name;
public:
First(char* name)
{
this->name = new char[strlen(name)+1];
}
~First()
{
cout<<"~First()"<<endl;
delete []name;
}
};
class Second :public First
{
private:
char* name;
public:
Second(char* fName, char* sName)
:First(fName)
{
name = new char[strlen(sName)+1];
}
~Second()
{
cout<<"~Second()"<<endl;
delete []name;
}
};
class Third :public Second
{
private:
char* name;
public:
Third(char* fName, char* sName, char* tName)
:Second(fName, sName)
{
name = new char[strlen(tName)+1];
}
~Third()
{
cout<<"~Third()"<<endl;
delete []name;
}
};
int main()
{
First* f1 = new Third("aaa","bbb","ccc");
delete f1;
return 0;
}
delete f1; => 이 경우 First 클래스의 소멸자와 Second, Third 클래스의 소멸자가 동시에 호출되어야 한다. 하지만 그렇지 않다.
실행결과에서 보이듯, 객체의 소멸을 First형 포인터로 명령하니 First 클래스의 소멸자만 호출되었다.
따라서 이러한 경우에는 "메모리의 누수(leak)" 가 발생하게 된다.
그러니 객체의 소멸과정에서는 delete 연산자에 사용된 포인터 변수의 자료형에 상관없이 모든 소멸자가 호출되어야 한다.
그리고 이를 위해서는 다음과 같이 소멸자에 virtual 선언을 추가하면 된다.
#include <iostream>
#include <cstring>
using namespace std;
class First
{
private:
char* name;
public:
First(char* name)
{
this->name = new char[strlen(name)+1];
}
virtual ~First()
{
cout<<"~First()"<<endl;
delete []name;
}
};
class Second :public First
{
private:
char* name;
public:
Second(char* fName, char* sName)
:First(fName)
{
name = new char[strlen(sName)+1];
}
virtual ~Second()
{
cout<<"~Second()"<<endl;
delete []name;
}
};
class Third :public Second
{
private:
char* name;
public:
Third(char* fName, char* sName, char* tName)
:Second(fName, sName)
{
name = new char[strlen(tName)+1];
}
virtual ~Third()
{
cout<<"~Third()"<<endl;
delete []name;
}
};
int main()
{
First* f1 = new Third("aaa","bbb","ccc");
delete f1;
return 0;
}
가상함수와 마찬가지로 소멸자도 상속의 계층구조상 맨 위에 존재하는 기초 클래스의 소멸자만 virtual로 선언하면, 이를 상속하는 유도 클래스의 소멸자들도 모두 "가상 소멸자" 로 선언이 된다.
그리고 가상 소멸자가 호출되면, 상속의 계층구조상 맨 아래에 존재하는 유도 클래스의 소멸자가 대신 호출되면서, 기초 클래스의 소멸자가 순차적으로 호출된다.
'Programming > C++' 카테고리의 다른 글
객체(Instance) 와 멤버함수(Method) 의 관계 (0) | 2012.08.22 |
---|---|
참조자의 참조 가능성 (0) | 2012.08.20 |
순수 가상함수(Pure Virtual Function)와 추상 클래스(Abstract Class) (0) | 2012.08.19 |
가상 함수 (Virtual Function) (0) | 2012.08.19 |
상속과 다형성 (0) | 2012.06.23 |