값으로 스마트 포인터를 반환합니다.
말했듯이 참조로 반환하면 참조 횟수가 제대로 증가하지 않아 부적절한 시간에 무언가를 삭제할 위험이 있습니다. 그것만으로도 참조로 반환하지 않을 충분한 이유가 될 것입니다. 인터페이스는 견고해야합니다.
비용 문제는 현재 RVO ( Return Value Optimization) 덕분에 문제가되고 있으므로 최신 컴파일러에서 증가-증가-감소 시퀀스 또는 이와 유사한 것이 발생하지 않습니다. 따라서 a를 반환하는 가장 좋은 방법 shared_ptr
은 단순히 값으로 반환하는 것입니다.
shared_ptr<T> Foo()
{
return shared_ptr<T>(/* acquire something */);
};
이것은 최신 C ++ 컴파일러에 대한 분명한 RVO 기회입니다. Visual C ++ 컴파일러는 모든 최적화가 꺼져 있어도 RVO를 구현한다는 사실을 알고 있습니다. 그리고 C ++ 11의 이동 의미론을 사용하면이 문제는 훨씬 덜 관련성이 있습니다. (하지만 확실한 방법은 프로필을 작성하고 실험하는 것뿐입니다.)
여전히 확신이 서지 않는다면, Dave Abrahams는 가치 반환에 대한 논쟁을 하는 기사 를 가지고 있습니다. 여기에 스 니펫을 재현합니다. 나는 당신이 전체 기사를 읽는 것이 좋습니다.
솔직히 말해서 다음 코드가 기분이 어떤가요?
std::vector<std::string> get_names();
...
std::vector<std::string> const names = get_names();
솔직히 더 잘 알아야하는데 긴장이된다. 원칙적으로, 경우에 get_names()
반환, 우리가 가지고 복사 vector
의 string
들. 그런 다음 초기화 할 때 다시 복사
names
해야하고 첫 번째 복사본을 삭제해야합니다. string
벡터에 N이있는 경우 각 복사본에는 문자열 내용이 복사 될 때마다 N + 1 메모리 할당과 캐시에 비 친화적 인 데이터 액세스가 많이 필요할 수 있습니다.
그런 종류의 불안에 맞서기보다는 불필요한 사본을 피하기 위해 참조에 의한 전달을 자주 사용합니다.
get_names(std::vector<std::string>& out_param );
...
std::vector<std::string> names;
get_names( names );
불행히도이 접근 방식은 이상적이지 않습니다.
- 코드가 150 % 증가했습니다.
- 우리는
const
이름을 변경하기 때문에 -ness 를 떨어 뜨려야했습니다.
- 함수형 프로그래머가 우리에게 상기시키고 싶어하는 것처럼, 돌연변이는 참조 투명성과 방정식 추론을 약화시켜 코드를 추론하기 더 복잡하게 만듭니다.
- 더 이상 이름에 대한 엄격한 값 의미 체계가 없습니다.
그러나 효율성을 얻기 위해 이런 식으로 코드를 엉망으로 만드는 것이 정말로 필요합니까? 다행히도 대답은 '아니오'로 판명되었습니다 (특히 C ++ 0x를 사용하는 경우에는 그렇지 않습니다).