스마트 포인터 : 누가 개체를 소유하고 있습니까? [닫은]
C ++는 메모리 소유권, 즉 소유권 의미론에 관한 것 입니다.
해당 메모리를 해제하는 것은 동적으로 할당 된 메모리 청크 소유자의 책임입니다. 따라서 누가 메모리를 소유하는지 확인합니다.
C ++이 유형에 소유권 의해 설명되어 있습니다에서는 원시 포인터 따라서 좋은 아주 드문 (없다 (IMO) C ++에서 내부에 프로그램 싸여있다 희귀 하지 않을 원시 포인터 (원시 포인터 따라서 소유권을 유추없는 것처럼 우리가 할 수 누가 메모리를 소유하고 있는지 알 수 없습니다).
네이티브, 각 원시 포인터가 자체 스마트 포인터 래퍼 유전자 서열 클래스에 원시 포인터가 저장되어있는 경우는 거의 없습니다. ( NB : 당신이 물건을 소유하지 않는 당신은 물건이 범위를 벗어나서 파괴 될 때를 알 수 없기 때문에 보관할 가능성이 있습니다.)
따라서 질문 :
- 사람들이 어떤 유형의 소유권 의미론을 만났습니까?
- 그 의미를 구현하는 데 사용되는 표준 클래스는 무엇입니까?
- 어떤 상황에서 유용하다고 생각하십니까?
답변 당 1 가지 유형의 의미 적 소유권을 유지하여 식별 적으로 투표 할 수 있습니다.
요약 :
개념적으로 스마트 포인터는 단순하고 순진한 구현이 있습니다. 나는 많은 시도 된 구현을 구현하지만, 일상적인 사용과 예제에서는 분명하지 않은 방식으로 항상 깨달았습니다. 따라서 나는 항상 자신의 롤링보다는 라이브러리에서 잘 테스트 된 스마트 포인터를 사용하는 것이 좋습니다. std::auto_ptr또는 Boost 스마트 포인터 중 하나가 내 모든 요구를 듣는 것입니다.
std::auto_ptr<T>:
한 사람이 개체를 소유합니다. 소유권 이전이 허용됩니다.
사용법 :이를 통해 명시적인 소유권 이전을 표시하는 인터페이스를 정의 할 수 있습니다.
boost::scoped_ptr<T>
한 사람이 개체를 소유합니다. 소유권 양도는 허용되지 않습니다.
사용법 : 명시 적 소유권을 표시하는 데 사용됩니다. 소멸자에 의해 또는 명시 적으로 객체가 파괴됩니다.
boost::shared_ptr<T>( std::tr1::shared_ptr<T>)
복수 소유권. 이것은 간단한 참조 참조 포인터입니다. 참조로부터가 0에 도달하면 객체가 파괴됩니다.
: 많은 경우에 사용할 수 있습니다.
boost::weak_ptr<T>:
shared_ptr<T>포인터주기가 보관 된 상황에서 사용 됩니다.
사용법 : 사이클 만 공유 참조 횟수를 유지하는 경우 사이클이 사용을 유지하지 않습니다.
나를 위해,이 3 가지 종류는 내 요구의 대부분을 다루고 있습니다.
shared_ptr -카운터가 0에 도달하면 참조하면 할당 해제
weak_ptr-위와 동일하지만 shared_ptr할당을 해제 할 수없는 '노예'
auto_ptr-생성 및 할당 해제가 동일한 기능 내에서 발생하는 경우 또는 객체가 한 명의 소유자 전용으로 있어야합니다. 한 포인터를 다른 포인터에 할당하면 두 번째 포인터가 첫 번째 포인터에서 포인터를 훔쳤습니다.
나는 이것들에 대한 나만의 구현을 가지고 Boost있습니다.
여전히 참조로 호출을 전달합니다 ( const가능한 경우).이 경우 호출 된 메소드는 호출 시간 동안에 만가 활성 상태라고 가정해야합니다.
내가 사용하는 또 다른 종류의 포인터가 있습니다 . hub_ptr . 중첩 된 클래스 (일반적으로 가상 기본 클래스)에서 액세스 할 수있는 클래스가있을 때입니다. 이것은 weak_ptr그들에게 를 전달함으로써 해결할 수 있지만, shared_ptr그 자체 에는 없습니다 . 이뿐은 그보다 오래 살지 않는다는 것을 알기 때문에 hub_ptr을 전달합니다 (일반 포인터의 템플릿 래퍼 일입니다).
간단한 C ++ 모델
본 대부분의 내가 모듈에서 기본적으로 포인터를받는 [해석] 소유권 을 받지 않는 것으로 가정했습니다 . 실제로, 포인터의 소유권을 포기한 함수 / 방법은 매우 드물었 고 그 사실을 문서에 명시 적으로 표현했습니다.
이 모델은 사용자가 명시 적으로 할당 한 것의 소유자 만 가정합니다 . 그 밖의 모든 것은 자동으로 폐기 처분됩니다 (범위 종료시 또는 RAII를 통해). C와 같은 모델로, 대부분의 포인터는 자동으로 또는 필요한 친구가 될 때 (대할 할당의 발생시) 수업을 할당 해제 할 수있는 수명 기간을 예측합니다.
이 모델에서, 원시 포인터는 자유롭게 순환하며 대부분 위험하지 않습니다. (그러나 개발자가 충분히 똑똑 할 때마다 참조를 대신 사용합니다).
- 원시 포인터
- std :: auto_ptr
- 부스트 :: 스코프 _ptr
스마트 뾰족한 C ++ 모델
스마트 포인터로 가득 찬 코드에서 사용자는 객체의 수명을 무시할 수 있습니다. 소유자는 사용자 코드가 아닙니다. 스마트 포인터 자체입니다 (다시 RAII). 문제는 참조 발행 스마트 포인터와 혼합 된 순환 참조가 치명 일 수 있으므로 공유 포인터와 약한 포인터를 모두 처리해야할 것입니다. 여전히 여전히 할 소유권이 있습니다 (원시 포인터보다 장점이 안심해도 약한 포인터는 아무것도 가리킬 수 없습니다).
- 부스트 :: shared_ptr
- 부스트 : : 약한 _ptr
결론
아니 내가 설명하는 모델 문제 를 제외하지 않는 한, 수신 포인터가되어 있지 소유권을 수신 하고 이 사람을 소유 누구인지 여전히 매우 중요하다 . 참조 및 / 또는 스마트 포인터를 많이 사용하는 C ++ 코드의 경우에도 마찬가지입니다.
공유 소유권이 없습니다. 그럴 경우 제어 할 수없는 코드에만 해당하는지 확인하십시오.
그것은 모든 것이 어떻게 상호 작용하는지 이해하도록 강요하기 때문에 문제의 100 %를 해결합니다.
- 공유 소유권
- boost :: shared_ptr
리소스가 여러 개체간에 공유되는 경우. 부스트 shared_ptr은 참조 계산을 사용하여 모든 사람이 확인되었을 때 리소스가 할당 해제되었는지 확인합니다.
std::tr1::shared_ptr<Blah> 가장 좋은 방법입니다.
부스트에서 포인터 컨테이너 라이브러리도 있습니다. 컨테이너의 컨텍스트에서만 개체를 사용하는 경우 스마트 포인터의 표준 컨테이너보다 약간 더 효율적이고 사용하기 쉽습니다.
Windows에는 COM 포인터 (IUnknown, IDispatch 및 friends) 와이 를 처리하기위한 다양한 스마트 포인터 (예 : ATL의 CComPtr 및 _com_ptr 클래스를 기반으로하는 Visual Studio의 "import"문에 의해 자동 생성 된 스마트 포인터가 있습니다) ).
- 한 명의 소유자
- boost :: scoped_ptr
메모리를 동적으로 할당해야하지만 블록의 모든 종료 지점에서 할당 해제되었는지 확인하려는 경우.
누수 걱정없이 쉽게 재 장착 및 해제 할 수있어 유용합니다.
나는 내 디자인에서 공동 소유권을 가질 수있는 위치에 있지 않았다고 생각한다. 사실, 내 머리 위에서 생각할 수있는 유일한 유효한 경우는 플라이 웨이트 패턴입니다.
yasper :: ptr은 대안과 같은 경량의 boost :: shared_ptr입니다. 내 (현재) 작은 프로젝트에서 잘 작동합니다.
http://yasper.sourceforge.net/ 의 웹 페이지에는 다음과 같이 설명되어 있습니다.
다른 C ++ 스마트 포인터를 작성하는 이유는 무엇입니까? 이미 C ++ 용 고품질 스마트 포인터 구현이 여러 개 있으며, 가장 두드러진 것은 Boost 포인터 판테온과 Loki의 SmartPtr입니다. 스마트 포인터 구현의 좋은 비교와 그 사용이 적절한 경우 Herb Sutter의 The New C ++ : Smart (er) Pointers를 읽어보세요. 다른 라이브러리의 확장 기능과는 달리 Yasper는 좁게 초점을 맞춘 참조 계수 포인터입니다. Boost의 shared_ptr 및 Loki의 RefCounted / AllowConversion 정책과 밀접하게 일치합니다. Yasper를 사용하면 C ++ 프로그래머가 Boost의 큰 종속성을 도입하거나 Loki의 복잡한 정책 템플릿에 대해 배울 필요없이 메모리 관리를 잊을 수 있습니다. 철학
* 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기능을 가진 모든 유형 은 소유권이 동일한 유형의 다른 인스턴스로 전환 될 때까지 소유하는 일부 콘텐츠에 대한 스마트 참조 로 간주 될 수 있습니다 . 각 인스턴스는 ID를 유지하지만 새 콘텐츠에 바인딩됩니다. 안전하게 리 바인딩 할 수있는 참조와 같습니다.
(콘텐츠를 가져 오기 위해 명시 적으로 역 참조 할 필요가 없기 때문에 스마트 포인터가 아니라 스마트 참조입니다.)
이것은 auto_ptr이 덜 필요하다는 것을 의미합니다. 타입이 좋은 swap기능을 가지고 있지 않은 틈새를 채우기 위해서만 필요 합니다. 그러나 모든 표준 컨테이너는 그렇습니다.
- 한 명의 소유자 : Aka delete on Copy
- std :: auto_ptr
객체의 작성자가 명시 적으로 다른 사람에게 소유권을 넘기고 싶을 때. 이것은 또한 내가 제공하는 코드에 문서화하는 방법이며 더 이상 추적하지 않으므로 완료되면 삭제하십시오.
참고 URL : https://stackoverflow.com/questions/94227/smart-pointers-who-owns-the-object
'IT' 카테고리의 다른 글
| 지퍼가 왜 코 모나드인지 이해 (0) | 2020.07.28 |
|---|---|
| BookSleeve의 ConnectionUtils.Connect ()를 사용하여 Redis 메시지 버스 장애 조치와 함께 SignalR 사용 (0) | 2020.07.28 |
| WiFi를 통해 한 Android 스마트 폰에서 다른 스마트 폰으로 라이브 스트림 비디오 (0) | 2020.07.28 |
| Xcode 6.4 선택한 응용 프로그램 (0) | 2020.07.28 |
| 비밀 요점을 공개로 바꾸려면 어떻게해야합니까? (0) | 2020.07.28 |