본문 바로가기
개발/C, C++

C++ 스마트 포인터 : unique_ptr

by 피로물든딸기 2021. 10. 16.
반응형

C, C++ 전체 링크

 

참고

- 전략 패턴 (Strategy Pattern)

 

unique_ptr는 하나의 포인터만 허용하도록 하는 스마트 포인터다.

 

unique_ptr는 해당 자원에 대한 유일한 소유권을 가지는 특징 덕분에 

메모리 누수를 방지하고 자원 관리를 간편하게 해준다.

(RAII, Resource Acquisition Is Initialization 객체가 소멸될 때, 자동으로 해당 메모리가 해제된다.)

 

unique_ptr는 얕은 복사가 발생할 가능성을 사전에 차단한다.

즉, 오직 하나의 포인터만 존재할 수 있도록 한다.

여러 포인터가 동시에 하나를 가르킬 수 없도록 막는다.

 

따라서 아래의 myFood를 선언한 후, unqFood가 myFood를 가르키게 하는 것은 모두 컴파일 에러다.

unique_ptr<FOOD> myFood(new FOOD);

unique_ptr<FOOD> unqFood(myFood); // compile error

unique_ptr<FOOD> unqFood; 
unqFood = myFood; // compile error

 

unique_ptr도 reset으로 메모리를 해제할 수 있다.

#include <stdio.h>
#include <memory> // unique_ptr header
#include <iostream>

using namespace std;

class FOOD
{
private:
	int price = 0;
public:
	FOOD() { printf("FOOD created\n"); }
	~FOOD() { printf("FOOD deleted\n"); }

	virtual void printName() { cout << "FOOD Class" << endl; }
	virtual void printPrice() { cout << this->price << endl; }
	void printLine() { cout << "=================" << endl; }
};

int main(void)
{
	cout << "start main\n" << endl;

	unique_ptr<FOOD> myFood(new FOOD);

	//unique_ptr<FOOD> unqFood(myFood);

	/* unique_ptr<FOOD> unqFood;
	unqFood = myFood; */

	cout << "\nmy address : 0x" << myFood.get() << endl;

	myFood.reset();

	cout << "\nmy address : 0x" << myFood.get() << endl;


	cout << "\nend main\n" << endl;

	return 0;
}

 

reset으로 해제하지 않은 경우에는 end main 이후에 메모리가 해제된다.

 

unique_ptr로 배열을 만들고 싶다면 아래와 같이 배열임을 알려줘야 한다.

unique_ptr<FOOD[]> food(new FOOD[5]);

make_unique를 이용해 동적으로 할당된 객체를 생성할 수 있는데, 유니크 포인터를 만들 때 주로 권장된다.

메모리 누수를 방지하고 예외 안전성을 향상시킨다.

 

그리고 move를 이용해 유니크 포인터의 소유권을 다른 유니크 포인터로 이동할 수 있다. (복사보다 효율적)

 

사용 예시는 전략 패턴을 참고하자.

반응형

댓글