본문 바로가기
언리얼(Unreal)/엔진

24.12.07 언리얼(스마트 포인터에 대하여)

by alwaysyoung2 2024. 12. 7.
728x90
반응형
 

기본 포인터 vs 스마트 포인터?

기본 포인터

 

기본 포인터는 동적으로 할당된 메모리를 직접 관리해야 합니다. 만약 개발자가 delete를 호출하지 않으면 메모리 누수가 발생합니다.

 

이 메모리 누수를 해결하기 위해 나온 것이 스마트 포인터 입니다.

 

스마트 포인터는 자동으로 메모리 해제를 처리합니다.

스마트 포인터 객체가 더 이상 필요 없게 되면(스코프를 벗어나면) 내부적으로 메모리를 자동으로 해제합니다.

#include <iostream>
#include <memory>  // 스마트 포인터를 사용하기 위해 필요
using namespace std;

int main() {
    unique_ptr<int> ptr = make_unique<int>(42);  // 스마트 포인터 생성
    cout << *ptr << endl;  // 출력: 42
    // 자동으로 메모리 해제 (delete 필요 없음)
    return 0;
}

 

주요포인터의 종류는 std::unique_ptr, std::shared_ptr, 그리고 std::weak_ptr가 있습니다.

 

 

 std::unique_ptr독점 소유(Exclusive Ownership)

#include <iostream>#include <memory>class Toy
{
public:
    Toy() { std::cout << "새 장난감이 만들어졌어요!" << std::endl; }
    ~Toy() { std::cout << "장난감이 없어졌어요..." << std::endl; }
};

int main()
{
    // unique_ptr이라는 상자에 장난감을 넣어요
    std::unique_ptr<Toy> myToy = std::make_unique<Toy>();

    // 상자의 소유권을 친구에게 넘겨요 (myToy는 이제 장난감을 잃어요)
    std::unique_ptr<Toy> friendsToy = std::move(myToy);

    if (!myToy)
    {
        std::cout << "나는 이제 장난감이 없어!" << std::endl;
    }

    // 프로그램 종료 시 friendsToy도 범위를 벗어나며 장난감이 해제됩니다
    return 0;
}

  • 독점 소유: 동일한 객체를 다른 unique_ptr이 소유할 수 없습니다.
  • 이동(Transfer) 가능: 소유권은 복사되지 않고 이동할 수 있습니다 (std::move 사용).
  • 자동 해제: 포인터가 범위를 벗어나면 메모리가 자동으로 해제됩니다.

 

독점이 있다면 공동도 있지 않을까?

std::shared_ptr공유 소유(Shared Ownership)

 

  • 특징: 한 스마트 포인터만 객체를 소유할 수 있음.
  • 다른 사람에게 소유권을 넘길 수는 있지만, 복사할 수는 없음.

#include <iostream>#include <memory>class Toy
{
public:
    Toy() { std::cout << "새 장난감이 만들어졌어요!" << std::endl; }
    ~Toy() { std::cout << "장난감이 없어졌어요..." << std::endl; }
};

int main()
{
    // 여러 사람이 장난감을 공유할 수 있는 상자
    std::shared_ptr<Toy> toyBox1 = std::make_shared<Toy>();

    {
        // 다른 친구가 같은 장난감을 공유해요
        std::shared_ptr<Toy> toyBox2 = toyBox1;
        std::cout << "두 사람이 장난감을 가지고 있어요!" << std::endl;
    } // toyBox2가 소멸되었지만 toyBox1은 여전히 장난감을 가지고 있어요

    std::cout << "이제 한 사람만 장난감을 가지고 있어요!" << std::endl;

    // toyBox1이 범위를 벗어나면 장난감이 해제됩니다
    return 0;
}

 

std::weak_ptr약한 참조(Weak Reference)

 

 

  • 특징: 객체를 참조하지만 소유권이 없음.
  • 주로 순환 참조 문제를 해결할 때 사용.

#include <iostream>#include <memory>class Toy
{
public:
    Toy() { std::cout << "새 장난감이 만들어졌어요!" << std::endl; }
    ~Toy() { std::cout << "장난감이 없어졌어요..." << std::endl; }
};

int main()
{
    // shared_ptr로 장난감을 소유하는 상자
    std::shared_ptr<Toy> toyBox = std::make_shared<Toy>();

    // weak_ptr로 장난감이 여전히 있는지 확인할 수 있어요
    std::weak_ptr<Toy> weakFriend = toyBox;

    if (auto sharedToy = weakFriend.lock())  // shared_ptr로 변환 성공
    {
        std::cout << "장난감이 여전히 있어요, 내가 볼 수 있어요!" << std::endl;
    }
    else
    {
        std::cout << "장난감이 없어졌어요..." << std::endl;
    }

    // toyBox가 소멸되면 장난감도 해제됩니다
    toyBox.reset();

    if (auto sharedToy = weakFriend.lock())  // shared_ptr로 변환 실패
    {
        std::cout << "장난감이 여전히 있어요, 내가 볼 수 있어요!" << std::endl;
    }
    else
    {
        std::cout << "장난감이 없어졌어요..." << std::endl;
    }

    return 0;
}

 

스마트 포인터 요약

스마트 포인터특징비유

unique_ptr 한 객체를 하나의 스마트 포인터만 소유. 복사 불가능, 소유권 이동 가능. "자동차 열쇠는 한 사람만 가질 수 있음."
shared_ptr 여러 스마트 포인터가 객체를 공유. 마지막 포인터가 소멸될 때 메모리 해제. "여러 명이 공동으로 집을 소유함."
weak_ptr 객체를 참조하지만 소유권 없음. 주로 shared_ptr와 함께 순환 참조를 방지하는 데 사용. "집을 빌려 쓰는 사람처럼, 소유하지는 않음."

 

728x90
반응형