2021 시작

우리가 MAIN라는 기본 클래스와 SUB라는 파생클래스가 있는데 이 두 개로 팩토리 함수를 호출하고 객체를 삭제한다고 치자

class MAIN 
{
public:
	MAIN() { cout << "생성" << endl; }
	virtual ~MAIN() { cout << "MAIN" << endl; }

};
class SUB : public MAIN 
{
public:
	
	SUB() {cout << "생성" << endl;}
	~SUB() { cout << "SUB" << endl; }

};

int _tmain() 
{
	MAIN* main = new SUB;
	.............
    ............
	delete main;
}

 

이런 코드가 있다. 그런데 우리가 정상적으로 delete main에 도달하면 걱정이 없을 것이다. 하지만 실수로 delete에 도달하지 못하고 함수를 끝내버릴 수도 있다. 사이에 return이 들어간다던가~ 아니면 예외가 터져버린다던가~ 이런 식으로 말이다. 그러면 이 자원은 누수된 자원이 된다. 하지만 C++에서 제공해주는 스마트 포인터가 있다 이 포인터들은 내가 할당 해제를 시켜주지 않아도 할당이 해제된다. 여러 가지가 있지만 shared_ptr을 보여주겠다

 

class MAIN 
{
public:
	MAIN() { cout << "생성" << endl; }
	~MAIN() { cout << "MAIN" << endl; }

};
class SUB : public MAIN 
{
public:
	
	SUB() {cout << "생성" << endl;}
	~SUB() { cout << "SUB" << endl; }

};

int _tmain() 
{
	shared_ptr<MAIN>cm(new SUB);			//스마트 포인터
	
}

 

이게 끝이다. 하지만 이것들도 단점이 있다. 배열으로도 할당이 가능하지만 스마트 포인터의 소멸자에선 delete[]가 아닌 delete만 사용된다는 것이다. 말 그대로 배열은 제대로 처리를 하지 못한다는 것이다.

class MAIN 
{
public:
	MAIN() { cout << "생성" << endl; }
	~MAIN() { cout << "MAIN" << endl; }

};
class SUB : public MAIN 
{
public:
	
	SUB() {cout << "생성" << endl;}
	~SUB() { cout << "SUB" << endl; }

};

int _tmain() 
{
	shared_ptr<MAIN>cm(new SUB[1234]);			//스마트 포인터
	shared_ptr<int>integer(new int[5678]);		//배열
	
}

(boost에서는 배열도 가능하다더라, boost::scoped_array, boost::shared_array)

 

이것만은 잊지 말자!

1. 자원 누출을 막기 위해, 생성자 안에서 자원을 획득하고 소멸자에서 그것을 해제하는 RAII객체를 사용하자

2. 일반적을 ㅗ널리 쓰이는 RAII클래스는 tr1::shared_ptr 그리고 auto_ptr이지만 이 둘 가운데 tr1::shared_ptr이 복사 시의 동작이 직관적이기 때문에 대개 더 좋다. 반면 auto_ptr은 복사되는 객체(원본 객체)를 null로 만들어 버린다.

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading