2010-12-12 4 views
4

일부 상황에서 값 또는 참조 의미를 선택할지 여부에 대한 느낌 (아직, 희망합니다)이 없습니다. 적용 할 수있는 어림짐작 규칙이 있습니까?이 상황에서의 값 또는 참조 의미는 무엇입니까?

나는 일반적으로 내장 데이터 유형 (char, int, bool, double 등) 이외의 모든 것에 대한 참조를 선택합니다. 그러나 때때로 함수에서 참조를 반환 할 수 없기 때문에 포인터를 사용해야합니다. 다음 함수는이의 예입니다

Foo bar() 
{ 
    Foo f; 
    f.do_stuff(); 
    return f; 
} 

내가 푸 개체를 저장하는 부스트 :: shared_ptr의를 사용하는 거라고하지만, 그것은 아주 추한 객체로 작업합니다. 저는 현재 10 개 이상의 요소를 거의 가지고 있지 않을 deque를 반환하는 함수를 찾고 있습니다 (이것이 내가 가정 한 것입니다. 나는 확신 할 방법이 없습니다). 이것을 가치로 돌려 보내는 것이 좋을까요? 내 고려 사항이 조숙 한 최적화의 경우입니까?

+0

중복 가능성 (http://stackoverflow.com/questions/2139224/how-to-pass-objects-to-functions-in-c) – fredoverflow

답변

3

대부분의 컴파일러가 여분의 복사본을 최적화하기 때문에 값으로 반환하는 것이 좋습니다 (이것을 반환 값 최적화 또는 귀하의 경우에는 명명 된 반환 값 최적화라고 함).

그러나 관용적 방법은 당신은 항상이 작업을 수행 할 수

void bar(Foo& out) 
{ 
    out.do_stuff(); 
} 
+2

@fhd :이 접근 방식에는 두 가지 단점이 있습니다. 'out'이 원하는 상태에 있는지 확인해야하며, 입력하기가 더 번거롭고 자연스럽지 않습니다. 나는 보통 가치로 돌아가고 NRVO에 의지합니다. –

+0

@fhd : 그러나이 접근법에서는 장점이 있습니다. 함수 내부에서 객체를 생성하지 않으므로 예외적 인 안전을 해칠 수있는 가능한 건설 실패를 제거 할 수 있습니다. –

+0

소리가 합리적입니다, 감사합니다! – Neo

3

어떤 경우에도 을(참조 : f와 같은 로컬 변수)에 참조 또는 포인터로 반환하지 마십시오.

+0

[C++?의 함수에 객체를 전달하는 방법] 왜 ? (글자 수 제한 ..) –

+1

@Alex : 스택에 할당 되었기 때문에 함수가 스택 기반 변수의 할당을 해제하고 포인터 또는 참조가 유효하지 않게됩니다. – sashang

+0

@sashang : 문구가 불분명합니다 (심지어 잘못되었습니다). 그것은 "아무것도 반환하지 말아야한다 ...". 나는 downvote를 제공하고, @Ofir이 대답을 편집 할 때 downvote를 취소 할 것이다. –

0

입니다 :

Foo& bar(Foo& f) 
{ 
    f.do_stuff(); 
    return f; 
} 

을 그리고 다음과 같이 사용은 :

Foo f; 
bar(f); 

여기의 단점은 '당신이 할 수있다 bar()Foo 개체의 새 복사본이 제공됩니다. 중요한 경우 다음과 같이 수정해야합니다.

Foo& bar(Foo& f) 
{ 
    f = Foo(); 
    f.do_stuff(); 
    return f; 
} 

그러나 새로운 복사본이 생성되면 불필요한 초기화가 발생합니다. 또는 doSomething() 앞에 f을 검사하고 예상치 못한 경우 예외를 throw 할 수 있습니다.

0

변수 또는 개체의 상태를 유지하려면 참조를 사용하십시오 (즉, 호출 된 루틴에 의해 변수/개체에 대한 일부 처리가 완료된 후에 동일한 변수를 호출 루틴으로 다시 보내면). 함수에 큰 데이터를 전달하면 큰 볼륨 데이터의 이중 복사가있게됩니다.

또한 일부 개체의 비트 복제를 방지해야 할 경우 이러한 경우 클래스의 복사 생성자를 비공개로 만듭니다.

-1

내 일반적인 규칙은 다음과 같습니다

  1. 는 항상 값에 의해 패스를 사용합니다.

    간단합니다. 참조 빨아. 그들은 결코 소개되어서는 안됩니다.

  2. "데이터 구조 같은 값"이있는 경우 전달하십시오. "데이터 구조와 같은 객체"가 있으면 포인터를 전달합니다 (참조 의미, 값 전달).

    유형이 어떤 종류인지는 분명합니다 : 값 또는 개체. 당신이 돌연변이를 일으킬 수 있다면 그것의 개체.

관련 문제