2009-03-10 2 views
9

스마트 포인터를 더 사용하고자하는 프로젝트가 있습니다. 전반적으로, 나는이 목표에 성공적이었다. 그러나, 나는 "우수 사례"가 무엇인지 잘 모르는 한 가지를 발견했습니다.스마트 포인터가 보유해야하는 '포인터'를 반환합니다.

기본적으로 함수에서 "포인터"를 반환하고 싶지만 은 사용자가 스마트 포인터에 보유하고있는을 필요로합니다. 뿐만 아니라 특정 스마트 포인터 (공유 대 스코프)를 위임하고 싶지 않습니다.

대부분 문제는 scoped_ptrshared_ptr으로 업그레이드하는 적절한 방법이 없다는 것입니다 (이것이 내가 생각하기에 이상적인 해결책 일 것입니다). 나는 그들이 왜 이런 일을하지 않았는지 이해합니다. 왜냐하면 소유권 이전을 허용하기 때문에 std::auto_ptr 같은 몇 가지 문제가 발생할 수 있습니다.

그러나 소유권 이전은 의 경우이 사례의 경우 좋은 것으로 보입니다. 그래서 내 생각은 다음과 같이이다 :

// contrived example of factory pattern 
std::auto_ptr<A> func() { return std::auto_ptr<A>(new A); } 

scoped_ptrshared_ptr 모두가 std::auto_ptr에서 소유권을 가져 생성자를 갖고 있기 때문에 "확인"작동합니다.

제 질문은 이것이 좋은 습관입니까? 더 나은 해결책이 있습니까?

// similar to above example 
template <template <typename> class P> 
P<A> func() { return P<A>(new A); } 

실제로 나는 그것이 그것을 얻기 위해 몇 가지 작업을해야 할 것이라고 생각하는 것을 제외하고 잘 작동 수 : 유일한 대안은이 같은 반환 값으로 템플릿 템플릿을 사용하여 올 수있었습니다 scoped_ptr도 사용하십시오.

생각하십니까?

답변

11

사실 such example에 비얀 스트로브 스트 룹에 의해 제안되었으며, 좋습니다 입니다.

auto_ptr의 이동 의미 체계는 올바른 도구를 제공합니다. 예를 들어

:

auto_ptr<Foo> make_foo() 
{ 
    return auto_ptr<Foo>(new Foo); 
} 

Foo *raw_pointer=make_foo().release(); 
shared_ptr<Foo> shared_pointer=make_foo(); 
auto_ptr<Foo> auto_pointer=make_foo(); 

당신은 당신이 할 수있는 auto_ptr으로, 일반 포인터로 폴백 할 수 shared_ptr를 반환합니다. 당신은 항상 auto_ptr을 공유하지만 다른 방향으로 업그레이드 할 수는 없습니다.

또 다른 중요한 점, shared_ptrauto_ptr가하는 간단하고 아직 완전히 효율적인 작업이 을 훨씬 느립니다, 원자 참조 카운팅을 사용한다.

P.S. .: scoped_ptr은 복사 할 수 없으며 에는 기본 구성자가 없습니다. auto_ptr의 "덜 혼동스럽지 않은"버전과 비슷하지만 shared_ptr과 비교하면 tr1에 없습니다. 일반적으로 거기에 당신이 다른 스마트 포인터 유형으로 std::unique_ptr을 사용할 수 있어야 C++ 11 auto_ptr

+0

단일 스레드 빌드의 shared_ptr은 원자 참조 카운팅을 사용하지 않습니다. –

+0

맞습니다.하지만 기본적으로 멀티 스레드 버전에서는 빌드가 향상됩니다. – Artyom

+2

auto_ptr보다 scoped_ptr을 사용하면 포인터를 복사하지 않아도된다는 이점이 있습니다. scoped_ptr을 사용하면 안됩니다. 귀하의 의도가 auto_ptr 및 소유권 이전과 함께하는 것처럼 귀하의 의도 전달에 관한 것입니다. –

3

포인터를 반환하는 것으로 괜찮은 팩토리를 만드는 경우. 그리고 공장의 사용자는이 포인터를 어디에 어떻게 넣어야할지 스스로 결정을 내릴 수 있습니다.
스마트 포인터를 사용하도록 강요해야하는 경우 "잘못된"포인터를 사용하지 않도록 선택을 제한해야합니다.
그래서 boost :: shared_ptr. 하지만 MyClassPtr 또는 MyClass :: ptr에 typedef를 지정하는 것이 좋습니다.
여전히 공장은 "새로운"것과 같습니다. 내가 원할 때 std :: auto_ptr의 새로운 내부 결과를 넣는다. 하지만 나는 스마트 포인터를 원하지 않을 때 항상 "석방"을 강요하고 싶지는 않습니다. std::auto_ptr를 사용

+0

사실, 가능한 경우 스마트 포인터를 사용하고 싶습니다. –

+0

동의합니다. 우리는 모두 성인입니다. 알몸 포인터를 반환하고 코드의 사용자가 반환 값을 가장 잘 catch하는 방법을 결정하도록합니다. auto_ptr의 shared_ptr의 생성자가 사라질 것이라고 생각합니다 (auto_ptr은 더 이상 사용되지 않을 것입니다). –

+0

auto_ptr이 C++ 0x에서 depricated되면 unique_ptr이이를 대체합니다. 그렇다면 unique_ptr을 반환하는 것으로 전환합니다. – Aaron

1

이상 scoped_ptr를 사용하여 더 많은 장점이 std::unique_ptr을 생성자가 없습니다. 그런 리소스의 내부 목록을 유지한다면 아마도 std::shared_ptr을 사용하고 싶을 것입니다.

관련 문제