2010-07-05 6 views
19

전달을 통한 값 대 전달 참조를 올바르게 이해하고 싶습니다. 특히, 개체에 대한 증분 ++ 연산자의 접두사/접미사 버전을 살펴 보았습니다. 내가 제대로 접두사/후위 증가 연산자를 구현 한, 모든접미사/접미사 증가 연산자

class X{ 
private: 
    int i; 
public: 
X(){i=0;} 
X& operator ++(){ ++i; return *this; } //prefix increment 

X operator ++ (int unused){ //postfix increment 
    X ret(*this); 
    i++; 
    return ret; 
} 

operator int(){ return i; } //int cast 
}; 

첫째 :

은의 우리가 다음 클래스 X이 있다고 가정하자?

둘째, 접두어 연산자와 비교하여 후위 연산자가 얼마나 효율적입니까? 운영자의 각 버전을 사용할 때 얼마나 많은 수의 X 개체 복사본이 생성됩니까?

return-by-reference와 value-by-return에서 정확히 무슨 일이 일어나는지에 대한 설명은 내가 이해하는 데 도움이 될 수 있습니다.


편집 : 예를 들어, 다음 코드를 사용하여 ...

X a; 
X b=a++; 

... a와 b 지금 별명은?

+0

접미사에'i'를 후위로 올릴 필요가 없습니다. 사실, 나는 [FredOverflow suggests] (http://stackoverflow.com/questions/3181211/3181359#3181359)로하고 프리픽스 버전을 호출합니다. IMO는 실제로 구현을 재 구현하는 것보다 훨씬 관용적입니다. _ 암시 적 변환 연산자를 제거하십시오. _ 그것은 당신을 다치게 할 것입니다. (암시 적 변환 연산자를 작성한 세 번째와 마지막 시간은 2001 년이었고 1-2 년 후에 나는 미묘한 버그를 일으키고 그것을 제거했다는 것을 발견했습니다 - 이전의 모든 것들처럼.) – sbi

답변

17

올바른 구현입니다. 증분을하기 전에 다른 복사본을 만들어야하기 때문에 후위 연산자가 성능에서 더 나빠질 것이 일반적입니다 (그리고 이것이 제가 다른 것을 필요로하지 않는 한 항상 접두어를 사용하는 습관을 갖게 된 이유입니다).

참조 별 반환을 사용하면 l 값 참조를 현재 개체로 반환합니다. 컴파일러는 일반적으로 현재 객체의 주소를 반환하여이를 구현합니다. 즉, 객체를 반환하는 것은 숫자를 반환하는 것처럼 간단합니다.

그러나 반환 값을 사용하면 복사본을 만들어야합니다. 즉, (주소가 아닌) 반환하는 동안 복사 할 정보와 호출 할 복사 생성자가 있음을 의미합니다. 이 부분에서 성능이 향상됩니다.

구현의 효율성은 일반적인 구현과 비슷합니다.

편집 : 부록과 관련해서는 아니요 별칭이 아닙니다. 두 개의 개별 오브젝트를 작성했습니다. 값으로 돌아 오면 (그리고 후위 증가 연산자 내에서 새 객체를 만들 때)이 새로운 객체는 별개의 메모리 위치에 배치됩니다.

int a = 0; 
int& b = ++a; 

B가 참조하는 주소이다

그러나 다음 코드 A 및 B의 별명.

+2

일반적으로 올바른 모듈로 반환 값 최적화 (http://en.wikipedia.org/wiki/Return_value_optimization). –

2

운영자가 올바르게 구현되었습니다.

접두어 연산자에서 X 사본을 만들지 않습니다.

후위 연산자에서 한 복사본은 ret로 만들어지고 잠재적으로은 함수에서 반환 될 때 다른 복사본이 만들어 지지만 모든 컴파일러는이 복사본을 삭제합니다.

X operator++(int) 
{ 
    X copy(*this); 
    ++*this;   // call the prefix increment 
    return copy; 
} 

X 개체를 증가의 논리 따라서 단독 프리픽스 버전 내에 포함되어

15

접미사 증분에서 객체 자체의 프리픽스 증가 전화 더욱 관용적이다.

+0

그래,이 같은 정정 게시에서 날 자유롭게. '+ 1'은 나에게서. – sbi