2013-08-31 2 views
0

저는 현재 C++ 11 기능에 익숙해 지려고합니다. 내가 자발적으로 좋아하는 한 가지는 스마트 포인터, 특히 shared_ptr입니다. 그러나 일반적인 포인터를 shared_ptr에 할당하는 것을 허용하지 않는 것처럼 보입니다. 예를 들어make_shared를 사용하는 더 짧은 방법은 무엇입니까?

typedef shared_ptr<string> StringPtr 
... 
StringPtr x; 
... 
x = new string("bla"); 

적어도 VC2010에 실패하고 템플릿 인수 유형의 일반 포인터 과부하가 누락 shared_ptr::operator=에서의 인터페이스를 볼 때 나는 물론이를 이해할 수있다. 지금은 그냥 명시 적으로 shared_ptr 생성자를 사용하여 일반 포인터에서 shared_ptr를 만들 수 있습니다 즉

x = StringPtr(new string("bla")); 

하지만 내 의견이 중복 및 직관적이다

. 스마트 포인터에 일반 포인터를 할당 할 때 프로그래밍 의도를 가능한 많이 표현했다고 생각합니다. 구문을 추가하면 명확성이 크게 떨어지지 않고 가독성이 떨어집니다. 물론 스마트 포인터에 이미 "소유 된"일반 포인터를 할당하지 않는 것은 나에게 달린 것이지만 ...

가독성을 복원하는 동안 나는 make_shared<>을 우연히 만났습니다. 하지만 다시 라인

x = make_shared<string>("bla"); 

훨씬 더 읽기 쉽고 컴팩트 위의 스마트 포인터의 명시 적 구조 이상입니다. 물론 성능이 약간 더 좋을 수는 있지만 그게 내가하는 것만은 아닙니다. 그래서 내 의도는 인스턴스화하고 shared_ptr에 대해했던 것처럼 make_shared 함수 템플릿의 별명을 지정하는 것이 었습니다. 그러나 분명히

typedef make_shared<string> NewString 

는 전혀 유효하지 않습니다. 그래서 제 질문은 : 어떻게 가까운 글을 쓸 수 있습니까?

x = NewString("bla"); 

?

+3

제 생각에'std :: make_shared <...> (...)'은 읽을 수있을뿐만 아니라 여러분이하는 일을 명시 적으로 알려줍니다. –

+0

"전문화"에 귀하의 상황에 해당하지 않는 C++의 특정 정의가 있으므로 혼동을 피하기 위해 질문의 제목을 편집했습니다. –

+0

@ Joachim Pileborg : 기본적으로 당신 말이 맞습니다. 그것은 맛의 문제입니다. 하지만 밑줄이 싫어서 템플릿 괄호가 마음에 들지 않습니다 (물론 템플릿을 좋아합니다!). 나는 40 개의 괄호와 20 개의 템플릿 괄호를 가진이 intellisense 라인이 내 underperforming 브레인들에게 말하려고하는 것이 무엇인지 알아 내려고 노력할 때마다 나의 싫어함에서 강화된다. – oliver

답변

1

이 작동하지 않는 이유 :

typedef make_shared<string> NewString 

make_shared는 타입이 아니기 때문에, 그것은 기능입니다. 그래서 정말로 "이름을 변경"하고 싶다면, 래퍼 함수를 ​​만드십시오.

typedef shared_ptr<string> StringPtr 

StringPtr NewString(const char* str) 
{ 
    return make_shared<string>(str); 
} 

int main() 
{ 
    StringPtr x = NewString("bla"); // works 
} 

그러나, make_shared는 C에서 "표준 어휘는"++ 지금 본질적으로, 그래서 언제 누군가가 make_shared로 실행 있습니다, 그들은 바로이 무엇을 알고 (해야한다). NewString은 그 기능에 대한 힌트를 얻지 만 make_shared에 비해 상대적으로 아직 알려지지 않았으며 처음에는 소스 나 일종의 문서를 봐야 할 것입니다.


사이드 참고 : 그 안전하지 않은 때문에 shared_ptr의 원시 포인터의 할당을 허용하지 않습니다.

방법은 shared_ptr이며 참조 수 (예 : 삭제 자)를 보유하는 추가 제어 데이터 구조를 할당한다는 점에서 다릅니다. 이 제어 데이터 구조는 객체 자체와 별도로 유지됩니다.. 임의의 원시 포인터를 감안할 때 이미 연결된 제어 데이터 구조가 있는지 확인하는 것은 불가능합니다.따라서 원시 포인터 할당을 허용하면 객체가 서로 관련이있는 두 개 이상의 제어 데이터 구조를 가질 수 있습니다. 각 제어 데이터 구조는 서로 다른 참조 카운트를가집니다.

+0

대단히 감사합니다. 래퍼 함수가 너무 명백하기 때문에 나는 실제로 조금 어리 석다. :-) 어쩌면 내가 전역 함수가 허용되지 않는 C#에서 너무 많이 프로그래밍 되었기 때문에 나는 이것을 놓쳤을 것이다. 안전 문제에 관해서는 shared_ptr의 설계자가 염두에 두었던 것일 수도 있지만 shared_ptr (another_shared_ptr.get())과 같은 것을 작성하지 않기 때문에 안전이 내 의견으로는 완전히 상상이됩니다 ... 모든 악용 사례 할 수있는 일은 언젠가 끝날 것입니다. – oliver

+0

@ user2118609 : 사실, 그것은 결정적인 바보를 막을 수는 없습니다. 하지만'shared_ptr'을 잘못 사용하는 것이 더 어렵습니다. 항상 좋은 일입니다. –

관련 문제