[C++] 스마트 포인터

KWANHO PARK·2025년 4월 19일

CPP

목록 보기
24/24
/*
	shared_ptr
	make_shared : 객체와 참조 카운트를 하나의 메모리 블럭에 같이 할당. shared_ptr을 생성하는 함수
	shared_ptr는 참조 카운트를 통해 객체의 소유권 공유
	여러개의 shared_ptr이 객체를 참조할 수 있으며 레퍼런스 카운트가 0이 되면 메모리 자동 해제
*/
#include <iostream>

class MyClass {
public:
	MyClass() {
		std::cout << "MyClass Constructor call" << std::endl;
	}
	~MyClass() {
		std::cout << "MyClass Destructor call" << std::endl;
	}
	void func() {
		std::cout << "Siuuuuu shared_ptr" << std::endl;
	}
};

int main()
{
	std::shared_ptr<MyClass> ptr = std::make_shared<MyClass>();
	std::shared_ptr<MyClass> ptr2 = ptr;
	printf("ptr과 ptr2는 동일한 객체를 가리킴(공유)\n");

	ptr2->func();
	return 0;
}

/*
	스마트 포인터 unique_ptr
	객체의 생명 주기를 객체가 관리
	개발자의 메모리 관리 부담을 줄여줌
	unique_ptr - 소유권을 독점적으로 관리하는 스마트 포인터(auto_ptr 대체)
*/
#include <iostream>

class MyClass {
public:
	MyClass() {
		std::cout << "MyClass Constructor call" << std::endl;
	}
	~MyClass() {
		std::cout << "MyClass Destructor call" << std::endl;
	}
};

int main()
{
	std::unique_ptr<MyClass> ptr(new MyClass{});
	std::unique_ptr<MyClass> ptr2 = move(ptr);		// 소유권 이전

	return 0;
}

/*
	weak_ptr : 레퍼런스 카운트에 영향을 주지않는 스마트 포인터
*/
#include <iostream>

class MyClass {
public:
	MyClass() {
		std::cout << "MyClass Constructor call" << std::endl;
	}
	~MyClass() {
		std::cout << "MyClass Destructor call" << std::endl;
	}
	void func() {
		std::cout << "Siuuuuuu weak_ptr" << std::endl;
	}
};

int main()
{
	std::shared_ptr<MyClass> ptr = std::make_shared<MyClass>();		// C++14 이후부터 지원
	std::weak_ptr<MyClass> weakPtr = ptr;

	// weak_ptr은 순환참조를 방지
	std::shared_ptr<MyClass> ptr2 = weakPtr.lock();		// weak_ptr에서 shared_ptr로 변환
	if (ptr2) {
		std::cout << "weak_ptr로 변환한 shared_ptr 사용 가능" << std::endl;
	}

	return 0;
}

/*
	순환참조: 두 객체가 서로를 참조하고, 둘 다 shared_ptr을 사용하여 참조를 유지하는 경우 발생
*/
#include <iostream>

struct B;
struct A {
	std::shared_ptr<B> b_ptr;
};

struct B {
	//std::shared_ptr<A> a_ptr;		// 순환참조
	std::weak_ptr<A> a_ptr;
};

int main()
{
	std::shared_ptr<A> a(new A());
	std::shared_ptr<B> b(new B());

	a->b_ptr = b;
	b->a_ptr = a;

	return 0;
}

0개의 댓글