std::shared_ptr은 std::unique_ptr과 함께 C++11부터 사용 가능한 smart pointer 이다.
std::shared_ptr
is a smart pointer that retains shared ownership of an object through a pointer.
(http://en.cppreference.com/w/cpp/memory/shared_ptr)
std::unique_ptr과 다른점은 ownership을 공유(shared)한다는 점이다.
std::shared_ptr 객체를 만들때 한가지 문제가 되는 부분이 있는데, 아래와 같은 상황이 발생하지 않도록 주의해야 한다는 점이다.
Bad* p = new Bad;
std::shared_ptr<Bad> a1(p);
std::shared_ptr<Bad> a2(p); // ERROR! you may want to write std::shared_ptr<Bad> a2(a1);
a1과 a2는 (같은 raw pointer p를 갖는) 서로 다른 스마트 포인터이기 때문에 위 코드는 런타임에 아래처럼 죽게 된다. (mac clang-900.0.39.2)
./a.out
a.out(16448,0x7fff8e2d2340) malloc: *** error for object 0x7fc73b400340: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
우리가 raw pointer 를 아예 안쓰면 모르지만, 아래와 같은 경우는 난감하다.
void func(BadOrGood* p) {
std::shared_ptr<BadOrGood> a(p);
...
}
T 를 구현할 때 std::enable_shared_from_this<T> 를 상속하면 T의 객체가 자신의 shared_ptr 객체를 알 수 있게 해준다.
class Good : public std::enable_shared_from_this<Good> { ... };
std::shared_ptr<Good> a(p.shared_from_this());
이렇게 enable_shared_from_this 를 상속받고, shared_ptr에 raw pointer를 넣을때는 shared_from_this() 를 통해 shared_ptr을 얻어서 호출하면 안전하다.
사실 아직 문제가 있는데
shared_ptr 객체를 만들지 않고 shared_from_this()를 호출하면 std::bad_weak_ptr exception이 발생한다.(C++17부터, 그전에는 undefined behavior)
그리고, 여전히 첫번째 예제(Bad)처럼 실수하면 죽는다.
이를 막기 위해서, 직접 new 를 못하게 막아 두고 shared_ptr 객체가 생성되도록 해야 한다.
class Good : public std::enable_shared_from_this<Good> {
public:
std::shared_ptr<Good> create() { return std::make_shared<Good>();};
private:
Good() = default;
};
'프로그래밍 언어 > C&C++' 카테고리의 다른 글
[C++] 소스코드에서 컴파일러 구분하기? (0) | 2021.01.19 |
---|---|
[읽은 글] const correctness (0) | 2016.10.18 |
[C++11] std::function의 성능 (0) | 2015.05.29 |
GCC options (0) | 2013.12.05 |
[C++11] Range based for loop (4) | 2013.11.13 |