2017-11-15 2 views
-4

우선, std::weak_ptr의 일반적인 구현은 무엇입니까? 특히 std::weak_ptr의 제어 블록에 대한 포인터는 std::shared_ptr입니까?memcpy std :: weak_ptr을 사용할 수 있습니까?

std::shared_ptr 참조가 모두 사라진 경우 내부 제어 블록이 삭제 되었습니까? 그렇다면 std::weak_ptr::expired()은 메모리를 다시 사용하면 어떻게 제대로 작동합니까?


는 I는 std::weak_ptr 포함하는 객체가 있고, 나중에 처리 될 버퍼에 오브젝트를 memcpy 싶다. 스마트 포인터의 내부 동작을 어떤 식 으로든 깨뜨릴 것입니까?

+2

http://en.cppreference.com/w/cpp/types/is_trivially_copyable#Notes. ['std :: weak_ptr'] (http://en.cppreference.com/w/cpp/memory/weak_ptr/weak_ptr)에는 올바르게 읽으면 중요한 생성자가 있습니다. – Justin

+1

@ Justin non-trivial 생성자의 존재는 문제가되지 않으며, 단순한 복사 또는 이동 생성자 만 존재합니다. 그러나,'weak_ptr'를 복사 할 때 제어 블록을 수정해야하기 때문에, 구현시 사소한'std :: weak_ptr' 복사 생성자를 가질 수 없습니다. –

+0

"_particularly std :: weak_ptr std :: shared_ptr_의 제어 블록에 대한 포인터"가 아니라 "**"** – curiousguy

답변

5

모든 std::shared_ptr 개체가 사라지면 제어 블록이 여전히 존재합니다 (즉, std::weak_ptr의 작동 방식). 참조 된 개체 만 삭제됩니다.

이제 C++ 객체는 std::memcpyonly if it is trivially copyable을 통해 안전하게 복사 할 수 있습니다. TriviallyCopyable 개념의 요구 사항을 확인하면, std::weak_ptr은 중요하지 않은 복사 생성자가 있기 때문에이를 만족시키지 못합니다. 사실,이 생성자는 컨트롤 블록 내부의 weak-pointers-counter를 증가시킬 것이므로 std::memcpy으로 복사하면 불변성이 깨질 것입니다.

원시 버퍼에 std::weak_ptr을 저장하는 것은 일반적인 코드에서 끔찍한 생각처럼 들립니다. 버퍼는 일반적으로 직렬화, 데이터 전송/쓰기 등에 사용되며 이러한 모든 작업은 스마트 포인터에 대해 무의미합니다. 그러나, 당신은 당신이 버퍼에 저장해야한다는 것을 절대적으로 확신한다면, 당신은 placement new이 필요합니다

std::weak_ptr<T> the_one_i_want_to_copy; 

std::weak_ptr<T> * buffer = ...; 
new (buffer) std::weak_ptr<T> { the_one_i_want_to_copy }; 

을 주목 (buffer)new 후 :이 메모리를 할당하는 것이 아니라 이미 준비 사용하지 new을 알려줍니다 장소 (따라서 장소 멘토). buffer을 준비 할 때 필요한 크기와 정렬을 제공하십시오.

+0

을 포함합니다. 'optional'또는 'variant'와 같은 원시 버퍼의 다른 용도가 있습니다 '. 그러나 그것은 적어도 조금 이상합니다. 버퍼에'weak_ptr'을 복사해야한다면 올바른 도구는 새로운 배치입니다. –

+0

@DanielH 아주 좋은 지적입니다! 나는 이것을 답에 추가 할 것이다. 고마워. – lisyarus

관련 문제