2011-11-15 7 views
0

에 대한 참조를 반환하는이 코드를 살펴 :객체 생성자

Foo &Bar::Copy() 
{ 
    return Bar(); 
} 

클래스 바는 푸에서 상속되며, 푸는 추상 클래스입니다. 그러나 Bar()으로 전화를 걸어 돌아 오는 것이 안전할까요? 아니면 Copy() 함수의 끝 부분에서 해제 될 로컬 변수의 주소를 반환하겠습니까?

조언이 크게 감사합니다! 임시 Bar 객체가 ;에서 파괴되기 때문에

+0

가능한 복제본 [C++ 지역 변수로 돌아 가기 참조] (http://stackoverflow.com/questions/4643713/c-returning-reference-to-local-variable) – GWW

+0

@GWW - 아니요. 로컬 할당을 반환할지 여부를 계산하는 생성자를 반환하는지 여부는 알 수 없습니다. 아마 같은 일에 대해 혼란스러워하는 다른 사람들에게 유익 할 것입니다. – AutoBotAM

+0

실제로 rvalue가 비 const 참조에 바인딩되어 있기 때문에 컴파일되지 않아야합니다. – celtschk

답변

1

당신은 참조가 반환되는 암시 임시 개체에 생성자를 호출합니다. 기능과 비슷한 Clone()을 만들려는 경우 일반적으로 new으로 힙에 복제본을 만듭니다. 라이프 사이클 관리를 단순화하기 위해 일종의 스마트 포인터를 사용할 수 있습니다. 당신은의 ctor를 반환하지 않을 Bar &Bar::Copy()

0

이는 정의되지 않은 동작입니다.

Foo Bar::Copy() 
{ 
    return Bar(); 
} 

이 더 안전합니다. 하지만 @Cat Plus Plus와 @celtschk 덕분에이 방법으로 모든 정보가 손실되는 것을 깨달았습니다. Bar 특정 정보. Bar 오브젝트를 유지하려면 Copy() 오브젝트에 대한 참조 또는 포인터를 리턴해야합니다. 여기 UB 인 것처럼 우리는 다시 태어났습니다. 따라서 Bar은 동적으로 할당되어야하며, 참조/포인터는 Copy() 함수 밖에 있습니다. 누가 동적으로 생성 된 Bar 개체를 삭제해야합니까?

#include <memory> 
std::shared_ptr<Foo> Bar::Copy() 
{ 
    return std::shared_ptr(new Bar()); 
} 

shared_ptr은 자동으로이 작업을 수행합니다. Bar();를 호출 할 때

+2

두 번째 조각이 개체를 조각냅니다. –

+0

첫 번째 스 니펫은 개체도 슬라이스합니다. – celtschk

+0

@CatPlusPlus : 감사합니다. 대답을 편집했습니다. –

1

: 당신은 또한 서명을 사용하여 어떤 경우에는 형식 변환을 방지하기 공변 반환 형식을 적용 할 수 있습니다. Bar();을 호출하여 임시 개체를 만듭니다. 그런 다음 임시 객체에 대한 참조를 반환합니다.

C++에서의 ctor가 이름을 가지고 있지 않기 때문에, 당신은 보통 많은 일들을 할 수 없어 그럴 수와 같은 함수에 대한 포인터를 반환/점점 정상적으로 기능합니다. 여기에서 실제로 수행하려고하는 것은 분명하지 않지만 객체를 생성 할 무언가를 반환하려면 일반적으로 ctor를 호출하는 정적 멤버 함수를 정의하고 해당 정적 멤버 함수에 대한 포인터를 반환해야합니다 .

+0

장기적으로 볼 때'Foo *'포인터 배열을 만들려고합니다. (이론적으로 실제 프로그램에서는 Foo라고하지 않습니다.) 필자는 포인터의 수명이 정의되지 않은 동작을하는 경향이 있으므로 주소의 수명이 배열과 일치 할 수 있도록 복사본을 삽입하려고했습니다. jszpilewski가 언급했듯이 스마트 포인터를 사용하고 힙에 할당하는 것이 가장 좋을 것이라고 생각합니다. – AutoBotAM

+0

@AutoBotAM : Boost [ptr_vector] (http://www.boost.org/doc/libs/1_48_0/libs/ptr_container/doc/ptr_vector.html)를 살펴볼 수도 있습니다. –

+0

포인터 컨테이너 라이브러리는 내가 필요로하는 것처럼 보입니다. 시도 할 것이다. – AutoBotAM