소스
컴파일 및 결과
결론
#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.
댓글
댓글 쓰기