2011-07-28 7 views
1

일반적으로 나는 Google 스타일 가이드를 따르며, 나는 사물을 보는 방식과 잘 어울립니다. 또한 거의 독점적으로 boost :: scoped_ptr을 사용하여 단일 관리자 만 특정 객체의 소유권을 갖도록합니다. 그런 다음 나체 포인터를 전달합니다. 아이디어는 내 프로젝트가 구조화되어있어 객체를 사용하는 객체가 파괴 된 후에 객체의 관리자가 항상 파괴되도록합니다.scoped_ptr에 대한 약한 참조?

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Smart_Pointers

이 모든 좋은,하지만 난 그냥 주인이 너무가 삭제 된 사용 된 객체 전에 삭제하는 일이 불쾌한 작은 메모리 스톰 버그에 물린했다.

이제 모든 사람들이이 패턴에 대해 어리 석다는 점에서 위와 아래로 뛰어 오르기 전에 shared_ptr을 사용하지 않는 이유는 무엇입니까? 등등, 내가 정의되지 않은 소유자 의미를 갖고 싶지 않다는 점을 고려하십시오. shared_ptr이이 특별한 경우를 포착했지만 시스템의 사용자에게 잘못된 메시지를 전송합니다. 그것은 "누가 이걸 소유했는지 모르겠다. 너 일 수있다!"

범위 포인터에 약한 포인터를 사용했을 때 도움이 될만한 점은 무엇입니까? 실제로, 범위가 좁은 참조 목록이있는 범위가 지정된 포인터. 범위가 지정된 포인터가 소멸 될 때 제외됩니다. 이것은 단일 소유권 의미론을 허용 할 것이지만, 사용 객체가 내가 만난 문제를 잡을 수있는 기회를 제공한다.

scoped_ptr에 대한 추가 'weak_refs'포인터와 weak_ptr에서의 'next_weak_ptr'에 대한 추가 포인터를 희생시키면서 작은 단일 소유자, 다중 사용자 구조를 만들 수 있습니다.

디버그 기능 일 수도 있습니다. 따라서 '릴리스'에서 전체 시스템은 정상적인 크기의 scoped_ptr 및 약한 참조에 대한 표준 단일 포인터로 되돌아갑니다.

그래서 .....이 모든 후 내 질문은 다음과 같습니다

  1. 이미 내가 가 누락 STL/부스트 이러한 포인터/귀갑가 있습니까, 아니면 그냥 내 자신의 롤해야 ?
  2. 더 좋은 방법이 있습니까? 여전히 단일 소유권 목표를 충족합니까?

건배, 쉐인

+2

표준 또는 라이브러리 구현에 대해 알지 못합니다. 설명했던 것을 구현한다면, 누군가가 weak_ptr에서 미처리 포인터를 가져 와서 캐시 한 경우를 감지하기를 원하는 것처럼 shared_ptr/weak_ptr을 향상시키는 것과 매우 유사한 구현으로 끝날 것입니다. 당신은 단지 shared_ptr/weak_ptr을 사용하고 "manager"에서 그것이 유지하고있는 shared_ptr이 객체를 파괴하려고 할 때 유일하다는 것을 주장하기를 원한다고 말했을 것입니다. –

답변

6

  2. 여전히 내 단일 소유권 목표를 충족하는 더 좋은 방법이 있나요?

shared_ptr를 사용하십니까하지만, 그 클래스의 불변과 공용 인터페이스의 일부 있도록 클래스 멤버로 만 weak_ptr를 얻을 수있는 방법을 제공합니다.

물론 병리학 적 코드는 자신이 원하는만큼 자신의 shared_ptr을 그대로 유지할 수 있습니다. Murphy (Sutter의 말을 사용)에 대해서만 마키아 벨리 (Machiavelli)를 보호하려고하는 것은 좋지 않습니다. 반면에, 유스 케이스가 비동기라면, weak_ptr을 잠그는 것이 shared_ptr을 돌려 준다는 사실이 특징 일 수 있습니다!

+0

실제로 소유권 문제를 숨기는 좋은 방법입니다. 나는 그것을 좋아한다. :) – Shane

3

shared_ptr은이 특별한 경우를 포착했지만 시스템의 사용자에게 잘못된 메시지를 보냅니다. 그것은 "누가 이것을 소유했는지 모르겠다. 그것은 너 일 수있다!나는이 누구 소유 모른다 "

shared_ptr을 의미하지 않는다"는 우리는이를 소유 ". 그것은 의미한다". "하나의 엔티티는 것을 의미하지 않는다 독점 소유권이없는해서 사람 그 그것을 소유 할 수 있습니다. shared_ptr을의 목적은 공유하는 모든 사람들이 합의 될 때까지 그것이 파괴되어야한다 포인터가 파괴되지 않도록하는 것입니다

을.

것은 이러한 포인터/귀갑이 있습니까 이미 내가 놓쳤던 stl/boost에 벌써있다. 아니, 아니면 그냥 내 자신을 굴려 야합니까?

scoped_ptr과 똑같은 방법으로 shared_ptr을 사용할 수 있습니다. 공유 가능하다고해서 이 있다는 것을 의미하지는 않습니다. 그렇게하는 것이 가장 쉬운 방법 일 것입니다. 단일 소유권을 API 설정 규칙 대신 협약으로 만듭니다.

그러나 단일 소유자이지만 약한 포인터가있는 포인터가 필요하면 Boost에 포인터가 하나도 없습니다.

+0

안녕 Nicol, 예, 나는 "나는 누가 이걸 소유하고 있는지 모르겠다."선에서 다소 멜로 드라마가되고 있었다. 그렇다. 네가 맞다.) 요점에 관해서, 나는 시작하고있다. 단일 소유권을 시행하고 shared_ptr 접근 방식으로 롤업하는 실천을 다시 생각해보십시오. – Shane

1

약한 포인터가 그만큼 도움이 될지 잘 모르겠습니다. 일반적으로 구성 요소 X가 다른 구성 요소 Y를 사용하는 경우 X에는 Y의 종단 인 을 알려야합니다. 포인터를 무효화하는 것이 아니라 목록에서 제거하거나 더 이상 작동 모드를 변경하지 않아야합니다 개체가 필요합니다. 몇 년 전, C++을 처음 시작했을 때 좋은 일반적인 솔루션을 찾기 위해 노력한 활동이있었습니다. 문제는 이었습니다. 지금까지 내가 아는 한, 좋은 대답은 전혀 없었습니다. 일반적인 해결책이 모두 발견되었습니다. 적어도 내가 수행 한 모든 프로젝트는 Observer 패턴을 기반으로 손으로 작성된 솔루션을 사용했습니다.

나는 내 사이트에 ManagedPtr을 가지고 있었는데, 여전히 올라 갔을 때, 당신이 묘사 한 것과 비슷한 정도로 을 행동했습니다. 실제로 사례가있는 경우를 제외하고는 항상 알림이 필요했기 때문에 결코 실제 용도로 사용되지 않았습니다. 그러나 구현하기가 어렵지 않습니다. 관리 대상 개체는 ManagedObject 클래스에서 파생되고 포인터 (ManagedPtr 및 원시 포인터가 아님)가 모두 전달됩니다. 포인터 자체는 ManagedObject 클래스로 등록되고 ManagedObject 클래스의 소멸자가 모두이를 방문하고 실제 포인터를 null로 설정하여 을 연결을 끊습니다. 그리고 물론 ManagedPtrisValid 함수를 가지고 있으므로 클라이언트 코드는 역 참조 전에 테스트 할 수 있습니다. 이것은 (에 관계없이 객체가 내 기업의 대부분은 객체 — 자신을 "소유"하고, delete this 일부 특정 입력에 대한 응답 할 관리 방법의) 당신이 을 경향이 누출 제외하고 잘 작동 무효 ManagedPtr (예를 들면 때마다 클라이언트 포인터가 두 개 이상있을 수 있으므로 을 컨테이너에 보관합니다. 개체가 죽을 때 어떤 조치를 취해야 할 경우 클라이언트는 여전히 알리지 않습니다.

+0

안녕하세요 제임스, 전에 "objectDeleting"함수와 같은 함수를 호출 한 후 모든 참조/포인터를 효과적으로 0으로 전에 비슷한 컨테이너를 구현했습니다. 실제로는 옵서버 패턴입니다. 내 매니저 경우에도 꼭 필요한 것은 아니라고 생각하기 시작했습니다. – Shane

0

QT를 사용하는 경우 QPointer은 기본적으로 QObject에 약한 포인터입니다.그것은 지적한 가치로 "나는 방금 파괴되었습니다"이벤트에 연결하고 필요에 따라 자동으로 무효화합니다. 그것은 QT의 고리를 뛰어 넘지 않는다면, 버그 추적에 필요한 것을 가져 오기위한 심각한 라이브러리입니다.

+0

감사합니다. Dennis, QT를 사용하지는 않지만 어쨌든 고맙습니다. – Shane