enable_shared_from_this

Stupidiot·2025년 3월 26일

Unreal & C++

목록 보기
1/5
post-thumbnail

std::enable_shared_from_this


  • C++에서 객체 자신의 std::shared_ptr을 안전하게 얻을 수 있도록 도와주는 기능.
  • std::shared_ptr<T>로 관리되는 객체에서 shared_from_this()를 호출하면 현재 객체를 관리하는 shared_ptr과 동일한 참조 카운트를 공유하는 새로운 shared_ptr을 생성함.
  • 이를 통해 객체의 참조 카운트가 분리되는 문제를 방지할 수 있음.

std::shared_ptr<T>(this) 사용 문제점


  1. 새로운 shared_ptr이 기존과 다른 참조 카운트를 가짐.
  2. 기존 shared_ptr과 관리가 분리되어, 객체가 조기 소멸될 위험이 있음.
  3. 잘못된 메모리 관리로 인해 delete가 두 번 호출될 수도 있음.
class Test {
public:
    void Show() { std::cout << "Test::Show()" << std::endl; }
};

std::shared_ptr<Test> p1 = std::make_shared<Test>();
std::shared_ptr<Test> p2(p1.get());  // 에러 발생 : 참조 카운트 분리됨
  • p1p2서로 다른 참조 카운트를 가지며 객체를 관리하므로, 예상치 못한 메모리 해제 문제가 발생할 수 있음.

✅ 해결 방법: std::enable_shared_from_this<T> 사용


  • 클래스를 std::enable_shared_from_this<T>를 상속받게 하면, shared_from_this()를 이용해 기존 shared_ptr을 안전하게 참조 가능.
  • shared_from_this()는 기존 shared_ptr과 동일한 참조 카운트를 공유하므로, 객체의 중복 소멸 문제를 방지할 수 있음.
#include <iostream>
#include <memory>

class Test : public std::enable_shared_from_this<Test> {
public:
    std::shared_ptr<Test> GetShared() {
        return shared_from_this();  // 기존 shared_ptr과 동일한 참조 카운트 공유
    }
};

int main() {
    std::shared_ptr<Test> p1 = std::make_shared<Test>();
    std::shared_ptr<Test> p2 = p1->GetShared();  // 안전하게 동일한 shared_ptr 참조

    std::cout << "p1 count: " << p1.use_count() << std::endl;  // 2
    std::cout << "p2 count: " << p2.use_count() << std::endl;  // 2

    return 0;
}

shared_from_this()를 사용하면 p1p2동일한 참조 카운트를 공유하여 객체가 안전하게 관리됨.

❗주의할 점


  1. shared_from_this()를 사용하려면 객체가 반드시 std::shared_ptr로 관리되고 있어야 함.
    • new로 직접 생성한 객체에서 shared_from_this()를 호출하면 런타임 오류 발생.
    Test* rawPtr = new Test();
    std::shared_ptr<Test> p = rawPtr->shared_from_this();  // ❌ 오류 발생!
  2. std::make_shared<T>()를 사용하는 것이 더 안전함.
    • std::make_shared를 사용하면 객체와 컨트롤 블록을 한 번의 메모리 할당으로 생성하여 성능이 향상됨.

👓 정리


std::shared_ptr<T>(this)를 사용하면 참조 카운트가 분리되어 위험함.
✅ 이를 해결하기 위해 std::enable_shared_from_this<T>를 상속받고 shared_from_this()를 사용해야 함.
객체가 std::shared_ptr로 관리되지 않은 상태에서 shared_from_this()를 호출하면 오류 발생하므로 주의.
std::make_shared<T>()를 사용하는 것이 더 안전하고 성능도 좋음.

profile
행복하세요

0개의 댓글