소스
컴파일 및 결과
결론
#include <iostream>
using namespace std;
#define SHOWFUN() do { cerr << __PRETTY_FUNCTION__ << endl; } while(false)
class CParent1
{
public:
explicit CParent1() {SHOWFUN();}
~CParent1() {SHOWFUN();}
virtual void doWhat(void) const {SHOWFUN();}
};
class CChild1 : public CParent1
{
public:
explicit CChild1() {SHOWFUN();}
~CChild1() {SHOWFUN();}
virtual void doWhat(void) const {SHOWFUN();}
};
class CParent2
{
public:
explicit CParent2() {SHOWFUN();}
virtual ~CParent2() {SHOWFUN();}
virtual void doWhat(void) const {SHOWFUN();}
};
class CChild2 : public CParent2
{
public:
explicit CChild2() {SHOWFUN();}
virtual ~CChild2() {SHOWFUN();}
virtual void doWhat(void) const {SHOWFUN();}
};
class CChild3 : public CParent1
{
public:
explicit CChild3() {SHOWFUN();}
virtual ~CChild3() {SHOWFUN();}
virtual void doWhat(void) const {SHOWFUN();}
};
class CChild4 : public CParent2
{
public:
explicit CChild4() {SHOWFUN();}
~CChild4() {SHOWFUN();}
virtual void doWhat(void) const {SHOWFUN();}
};
class CGrandChild1 : public CChild1
{
public:
explicit CGrandChild1() {SHOWFUN();}
~CGrandChild1() {SHOWFUN();}
virtual void doWhat(void) const {SHOWFUN();}
};
class CGrandChild2 : public CChild2
{
public:
explicit CGrandChild2() {SHOWFUN();}
~CGrandChild2() {SHOWFUN();}
virtual void doWhat(void) const {SHOWFUN();}
};
template<typename _T>
void
show1(void)
{
cerr << "-------------------------------------------------------" << endl;
cerr << "Type: " << typeid(_T).name() << endl;
_T a;
}
template<typename _T1, typename _T2>
void
show2(void)
{
cerr << "-------------------------------------------------------" << endl;
cerr << "Type: " << typeid(_T2).name() << endl;
_T1* a(new _T2);
delete a;
}
int
main(int,char**)
{
show1<CChild1>();
show1<CChild2>();
show1<CChild3>();
show2<CParent1,CChild1>();
show2<CParent2,CChild2>();
show2<CParent1,CChild3>();
show2<CParent2,CChild4>();
show2<CParent1,CGrandChild1>();
show2<CParent2,CGrandChild2>();
return 0;
}컴파일 및 결과
$g++ -Wall vd.cpp -o vd
vd.cpp:7: warning: ‘class CParent1’ has virtual functions but non-virtual destructor
vd.cpp:15: warning: ‘class CChild1’ has virtual functions but non-virtual destructor
vd.cpp:55: warning: ‘class CGrandChild1’ has virtual functions but non-virtual destructor
$./vd
-------------------------------------------------------
Type: 7CChild1
CParent1::CParent1()
CChild1::CChild1()
CChild1::~CChild1()
CParent1::~CParent1()
-------------------------------------------------------
Type: 7CChild2
CParent2::CParent2()
CChild2::CChild2()
virtual CChild2::~CChild2()
virtual CParent2::~CParent2()
-------------------------------------------------------
Type: 7CChild3
CParent1::CParent1()
CChild3::CChild3()
virtual CChild3::~CChild3()
CParent1::~CParent1()
-------------------------------------------------------
Type: 7CChild1
CParent1::CParent1()
CChild1::CChild1()
CParent1::~CParent1()
-------------------------------------------------------
Type: 7CChild2
CParent2::CParent2()
CChild2::CChild2()
virtual CChild2::~CChild2()
virtual CParent2::~CParent2()
-------------------------------------------------------
Type: 7CChild3
CParent1::CParent1()
CChild3::CChild3()
CParent1::~CParent1()
-------------------------------------------------------
Type: 7CChild4
CParent2::CParent2()
CChild4::CChild4()
virtual CChild4::~CChild4()
virtual CParent2::~CParent2()
-------------------------------------------------------
Type: 12CGrandChild1
CParent1::CParent1()
CChild1::CChild1()
CGrandChild1::CGrandChild1()
CParent1::~CParent1()
-------------------------------------------------------
Type: 12CGrandChild2
CParent2::CParent2()
CChild2::CChild2()
CGrandChild2::CGrandChild2()
virtual CGrandChild2::~CGrandChild2()
virtual CChild2::~CChild2()
virtual CParent2::~CParent2()
결론
- virtual destructor 여부와 관계 없이 pointer를 delete하는 경우가 아니라면 일반 instance에 대해서는 동일한 결과를 내놓는다.
- virtual destructor가 아니면 부모 타입 pointer를 delete하는 경우 자식 instance의 destructor를 호출하지 않는다.
- 부모에서 한 번 virtual destructor로 정의하면 자식에서 virtual이 아니더라도 그 의미를 받는다. (CChild4)
- 요즘 컴파일러는 virtual method가 있는데도 virtual destructor를 정의하지 않았다고 궁시렁거려준다.
Powered by ScribeFire.
댓글
댓글 쓰기