스마트 포인:또는 소유습니다.[마감]
-
01-07-2019 - |
문제
C++모두에 대한 메모리 소유권
일명"소유권은 의미"
그것은 소유자의 책임의 덩어리의 동적으로 할당되는 메모리를 방출하는 메모리.이렇게 질문이 소유하는 메모리.
C++에서 소유권을 문서화한 유형에 의하여 원 포인터 내부에 싸여서에 따라서 좋은(IMO)C++프로그램 그것은 매우 드문[드물지 않은 결코]보 원 포인터를 전달(원 포인터가 없는 유추한 소유권 따라서 우리에게 말할 수 없다는 메모리를 소유하고 따라서 없이 주의 깊게 읽어의 문서 당신에게 말할 수 없는 사람은 책임에 대한 소유권).
반대로 그것은 희귀조 원 포인터를 저장 클래스에서는 각 원 포인터 내에 저장된 자신의 스마트 래퍼 포인터.(N.B.: 지 않는 경우에 자신의 개체해야 합되지 않을 저장하기 때문에 당신이 그것을 알 수 없다면 그것은 범위에서 벗고 합니다.)
그래서 질문:
- 어떤 유형의 소유권은 의미가 사람들을 통해 올?
- What 표준 클래스를 구현하는 데 사용되는 그 의미가?
- 어떤 상황에서 당신은 그들을 발견 유용한가?
할 수 있습 유지 1 유형의 시맨틱 소유권당이 대답할 수 있도록 선정하고 개별적으로 아래로
요약:
개념적으로 스마트 포인터는 간단하고 순진한 구현에서는 쉽습니다.본 많은 시도 구현하지만,변함없이들이 어떤 방법으로는 명확하지 않을 사용하여 캐주얼하고 예입니다.따라서 나는 권고 항상 사용하여 테스트하는"스마트 포인터"라이브러리에서 오히려 압연보다 당신의 자신입니다.std::auto_ptr 또는 하나의 부스트 스마트 포인터를 보일지 모두 커버됩니다.
std::auto_ptr<T>:
한 사람을 소유한 객체입니다.
그러나 소유권의 이전이 허용됩니다.
사용법:
======
이것은 당신이 인터페이스를 정의하여 명시적인 전송의 소유입니다.
부스트::scoped_ptr<T>
한 사람을 소유한 객체입니다.
소유권의 이전은 허용되지 않습니다.
사용법:
======
을 사용하여 명시적인 소유에 있습니다.
체에 의해 파괴 될 것이 소멸자 또는 할 때 명시적으로 재설정됩니다.
부스트::shared_ptr<T> (std::tr1::shared_ptr<T>)
여러 개의 소유입니다.
이것은 간단한 참조 계 포인터입니다.을 때 참조 횟수가 객체가 파괴되었다.
사용법:
======
이 여러 개 있을 수 있습 owers 평생 수없는 결정은 컴파일때 정해진다.
부스트::합니다<T>
사용 shared_ptr<T>.
는 상황에서는 사이클의 포인터 발생할 수 있습니다.
사용법:
======
사용 중지하는 주기에서 유체를 때 사이클을 유지하고 공유 refcount.
해결책
나를 위해,이러한 3 종류를 커버는 대부분의 내구:
shared_ptr
-참고-계산 할당 해제 때 카운터 도로
weak_ptr
-위와 같지만,그것은'슬레이브에 대한'a shared_ptr
, 할 수 없는 할당
auto_ptr
-을 때 생성 및 할당 해제 일어나 내부의 동일한 기능을 때 또는 개체 중 하나로 간주되어야자-유니다.을 할당할 때는 하나의 포인터,다른 두 번째는'스틸'체에서 첫 번째입니다.
나는 내 자신의 구현을 위한 이러한이지만,그들은 또한에서 사용 가능 Boost
.
내가 여전히 전달하여 객체 참조(const
가능),이 경우에는 방법이라고 가정해야의 객체가 살아있는 동안의 시간을 전화입니다.
또 다른 종류의 포인터를 사용하여 내가 전화 hub_ptr.그것은 있을 때는 객체에서 액세스할 수 있어야 합니다 개체 중첩에서 그것은(보통으로 가상의 기본 클래스).이는 해결할 수 있을 전달하여 weak_ptr
그들에게,그러나 그것은 없 shared_ptr
니다.그것이 알고 있는 이러한 객체지 않을 보다 더 오래 살고,그것을 전달하 hub_ptr 그들(그것은 단지 템플릿 래퍼를 일정한 포인터).
다른 팁
간단한 C++모델
에서 대부분의 모듈에서 나는 보았다 기본적으로,그것이 가능했을 것을 받는 것이었다 포인터 지 을 받 소유입니다.사실,기능/는 방법 포기한 소유권의 포인터를 모두 매우 드문하고 명시적으로 표현되는 사실의 문서입니다.
이 모델에서는 사용자가 소유자만의 그/그녀가 어떻게 명시적으로 할당.다른 모든 것은 자동으로 폐기(서 범위의 종료를 통해서 또는 RAII).이것은 C-와 같은 모델,확장된 사실에 의해 대부분의 포인터에 의해 소유하고 있는 개체를 할당을 자동으로 또는 필요할 경우(에서 말한 개체를 파괴,대부분),그리고 생명의 기간에 객체를 예측(RAII 는 당신의 친구,다시).
이 모델에서 원 포인터를 자유롭게 순환하고 대부분이 위험하지 않다(하지만 경우에는 개발자가 충분히 똑똑하고,그/그녀는 참조를 사용하는 대신 가능).
- 원 포인터
- std::auto_ptr
- 부스트::scoped_ptr
스마트 뾰족한 C++모델
에서 코드의 전체 스마트 포인터를 사용할 수 있는 희망을 무시하는 평생의 개체입니다.주인은 결코 사용자가 코드:그것은 스마트 포인터 자체(RAII,again). 문제는 순환을 참조 혼합조 계산 스마트 포인 치명적일 수, 는,그래서 당신은 모두 거래를 모두 포인터를 공유 및 약한 포인터입니다.그래서 당신은 여전히 소유권을 고려하는(약한 포인터가 있습 점 없는 경우에도,그것의 이점을 통해 원 포인터가 그것 말할 수 있는 그래서).
- 부스트::shared_ptr
- 부스트::합니다
결론
에 상관 없이 모델을 설명하는, 지 않으면 예외를 받고,포인터 지 를 받는 그 소유권 고 그것은 여전히 매우 중요하 모자.심지어는 C++코드를 사용하여 무겁게 참조 및/또는 스마트 포인터입니다.
이 없 공동 소유입니다.당신이 경우에는지 확인,그것만으로는 코드를 제어하지 않.
를 해결하는 100%의 문제 때문에,그것은 당신을 이해하는 모든 것이 어떻게 상호 작용.
- 공동 소유권
- 부스트::shared_ptr
면 리소스 사이에 공유되는 여러 개체입니다.Boost shared_ptr 사용하여 참조 계산을 확인하는 리소스를 할당할 때 모두가자의 의견을 더욱 쉽게 확인할.
std::tr1::shared_ptr<Blah>
은 자주 당신의 최선의 방법입니다.
- 한 소유자
- 부스트::scoped_ptr
할 때 필요한 메모리를 할당하는 동적으로만 그것은 확실히 얻을 할당에는 모든 종료 시점의 블록입니다.
내가 찾는 이용으로 쉽게 찾을 수 있 reseated 및 출시 걱정 없이 누출에 대해
나는 생각하지 않는 적었다는 위치에 있는 공동 소유권에 디자인이다.사실에서,최고의 내 머리만이 유효한 경우 생각할 수 있는 플라이급 패턴이다.
yasper::ptr 경량,부스트::shared_ptr 같은 대안입니다.그것은 잘 나에(지금)은 작은 프로젝트입니다.
에서 웹 페이지에 http://yasper.sourceforge.net/ 그것은 다음과 같습니다:
왜 다른 쓰 C++스마트 포인터가?거기에 이미 존재하는 여러 가지 고 품질 스마트 포인터 구현 C++,가장 눈에 띄게 향상 포인터를 제공하고 로의 SmartPtr.의 좋은 비교를 위해 스마트 포인터 구현 및을 때 그들의 사용은 적절한시허브 서터 새 C++:스마트(er)포인터입니다.에 대조적으로 한 특징 의 다른 도서관,Yasper 가 좁게 초점을 맞춘 참조 계산 포인터이다.그것에 해당과 긴밀하게 후원의 shared_ptr 로의 RefCounted/AllowConversion 정책입니다.Yasper 할 수 있습 C++프로그래머 잊지 메모리에 대해 관리 개의 대형 부스트 종속성을 배워야 하는 것에 대해 로의 복잡한 정책 템플릿이 있습니다.철학
* small (contained in single header) * simple (nothing fancy in the code, easy to understand) * maximum compatibility (drop in replacement for dumb pointers)
마지막 요점은 위험할 수 있습니다,이후 yasper 허가 위험한(아직용) 작업(과 같은 임무를 원 포인터를 수동 자료) 에서 허용하지 않는 다른 구현입니다.조심해야만 이러한 기능을 사용하는 경우 당신은 무슨 일을 하는지 알고!
거기에 또 다른 자주 사용하는 형태의 단 하나 양도 불가능한 소유자,그리고 그것은 바람직 auto_ptr
을 피할 수 있기 때문에 문제가 발생하여 auto_ptr
의 미치는 손상의 할당을 의미입니다.
나의 말한 다름 아닌 swap
.모든 유형에 적합한 swap
기능할 수 있습의 생각으로 스마트 참조 몇몇 콘텐츠는 그것을 소유하고 같은 시간까지 소유권이 이전하는 또 다른 인스턴스의 동일한 유형,그들을 교환하여.각각의 인스턴스지 그 정체나 바인딩하여 새로운 내용입니다.그것은 다음과 같은 안전하게 rebindable 참조.
(그것은 스마트 참조하기보다는 스마트 포인터 필요가 없기 때문에 명시적으로 역참조를 얻을에서는 콘텐츠가 포함 되었습니다.)
즉 auto_ptr 가 더 적은 필요가있다-그것은 단지를 채우기 위해 필요 틈이 유형이 없 swap
기능입니다.그러나 모든 std 컨테이너 않습니다.
- 한 소유자:Aka 에서 삭제를 복사
- std::auto_ptr
창조자의 개체고 싶은 명시적으로 손에게 소유권을 다른 사람.이것은 또한 방법으로 문서화하는 코드에서 내가 이것을 너와 나도 더 이상 추적 그것은 그래서 당신이 당신을 삭제 할 때 그것은 완료됩니다.