본문 바로가기

IT책/Effective c++

항목 7: 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자

으아 컴퓨터가 너무 안좋다 글 쓰는중에 갑자기 컴이 꺼지는바람에 ㅠㅠ 롤도 아슬아슬하게 돌아가넹 씁......

그리고 왜 항목4에서 7이냐 5와6은 어디갔느냐 귀찮아서 그냥 안적었따.  다시 본론으로 

virtual이 대충 어떻게 동작하시는지 알고있다고 생각하고 적겠다.(나도 잘 모르긴하지만.....)

 

#include <tchar.h>
#include <iostream>
using namespace std; 

class main_test  
{ 
public: 
	main_test() { cout << "베이스 생성!" << endl; } 
	virtual void func() = 0; ①

}; 

class sub_test1 : public main_test 
{ 

}; 
class sub_test2 : public sub_test1  
{ 

void func() { cout << "난 sub" << endl; } ②

}; 
int _tmain()  
{ 
	main_test *p = new sub_test2; 
	p->func(); 
}

 

 

 

대충 virtual을 사용하면 

결과가 이렇게 뜬다

main_test클래스에 virtual을 쓰지않았을때 p->func()을 실행시키면 얘는 main_test안에서 func함수를 찾을것이다 하지만 main_test에 virtual이 있어 sub_test2의 func함수로 이동한것이다. 걍 virtual이 앞에 있으면 베이스포인트에서 파생클래스로 날라간다고 생각하면된다

 

이렇게 말해도 도저히 내말을 이해못하겠다? 흐음....

 

 

나도 내가 무슨말 하는지 잘 모르고 있으니 그냥 봐줘라

쨋든 아까 말했던 virtual함수랑 똑같이 작동한다고만 생각하면된다.

 

#include <iostream>
#include <tchar.h>
using namespace std; 

class main_test  
{ 
public: 
	virtual ~main_test() { cout << "나는야 main_test" << endl; } 
}; 

class sub_test1 : public main_test 
{ 
public: 
	~sub_test1() { cout << "나는야 sub_test1" << endl; } 
}; 
class sub_test2 : public sub_test1  
{ 
public: 
	virtual ~sub_test2() { cout << "나는야 sub_test2" << endl; } 

}; 
int _tmain()  
{ 
	main_test *p = new sub_test2; 

	delete p; 
}

 

우리가 main_test *p = new sub_test2를 적으면

총 3개의 클래스를 우리가 할당?한것이다.

main_test -> sub_test1 -> sub_test2 순으로 말이다

 

그리고 우리는 delete를 했다.

그러면 삭제될때는 만들어질때의 역순으로 sub_test2->sub_test1->main_test 순으로 말이다 어떻게 이게 가능하는가?

virtual을 썼기때문이다 만약 우리가 virtual을 쓰지 않았다면 main_test에서 소멸자를 찾고 거기서 끝이 나서 sub_test1,2는 할당된채 그대로 방치됐을것이다.

아까 말했듯이 main_test클래스에서 virtual func를 만나면 그 파생클래스까지 끝까지 쫒아간다 sub_test2의 func를 찾아본다 sub_test2에 func가있으면 sub_test2에 있는func를 실행시키고 없으면 main_test의 func를 실행시킨다

 

 

미안하다 이게 내가 표현할수있는 한계다 내가 말해놓고 내가 무슨말을하고있는지 모른다니....... 슬픈일이다 

 

이것만은 잊지 말자!

*다형성을 가진 기본 클래스에는 반드시 가상 소멸자를 선언해야 한다, 즉, 어떤 클래스가 가상 함수를 하나라도 같고 있으면, 이 클래스의 소멸자도 가상 소멸자이어야 한다

*기본 클래스로 설계되지 않았거나 다형성을 갖도록 설계되지 않은 클래스에는 가상 소멸자를 선언하지 말아야 한다

*STL컨테이너 타입은 (예 : list,set,tr1::unordered_map)은 기본클래스로 설계되지않았다(가상소멸자가 아님) 조심하자