본문 바로가기
프로그래밍/More Effective C++

항목6. 증가 및 감소 연산자의 전위 / 후위 형태를 반드시 구분하자.

by 리뷰하는 (게임)프로그래머_리프TV 2011. 4. 29.

흔히 쓰는, ++, -- 연산자에 대해서 설명하고 있는 항목이다.

i++이나, ++i냐,
i--이냐, --i냐...
이것의 원리를 좀 알아 보고자 하는거 같다.

역시나 가장 기본은,
사용 후 더하느냐,
더한 후 사용 하느냐.

라고 보면 되겠지만
조금 자세히 파보자.

먼저 i++, ++i의 차이인데,
증가, 감소 연산자는 전위형태이든, 후위형태이든, 인자를 받지 않는(사용하지 않는) 구조이다.

그렇기 때문에 오버로딩을 하기 위해서 걸리는 매개변수의 타입이나, 갯수등으로 구별 하기가 까다로워 진 것이다.

이를 위해 약속한 것이,
전위는 그냥두고, 후위 형태는 int 타입의 인자를 받는 것으로 하자.
라고 약속하였다고 한다.

다음과 같이 말이다.

#include <iostream>

using namespace std;

class UPInt
{
public:
	UPInt& operator++();			// 전위 ++
	const UPInt operator++(int);	// 후휘 ++

	UPInt& operator--();			// 전위 --
	const UPInt operator--(int);	// 후위 --

	UPInt& operator+=(int);			// UpInts과 int에 대해 마련한
									// += 연산자

	...
};

UPInt i;

++i;		// i.operator++()를 호출
i++;		// i.operator++(0)를 호출

--i;		// i.operator--()를 호출
i--;		// i.operator--(0)를 호출​


다음은, 전위, 후위 형태의 내부 구조이다.

UPInt& UPInt::operator++()
{
	*this += 1;					// 증가
	return *this;				// 값을 반환 온다.
}

const UPInt UPInt::operator++( int )
{
	const UPInt oldValue = *this;	// 값을 가져 온다.
	++(*this);						// 증가

	return oldValue;				// 미리 가져온 값을 반환한다.
}​


쉽게 말해서 전위, 후위를 나누기 위해 후위의 경우 인자 int를 받고 있지만,
전혀 의미가 없다는 것을 알 수 있다.

이제 내부 구조를 조금 살펴 보면,
후위 구조의 경우 return 값이 const를 가지고 있다.
쉽게 말해서 i++++; 을 방지 하기 위해서 이다.
저 i++++을 사용한 의도가 뭘까?
i+=1 이후 계산 한 다음..? ++?
아니면 i +=2 이후 계산?
어떻게 생각해도 애매한 코드이다. 그런 부분을 일절 용납 하지 않겠다는 것이다.

마지막으로, ++i, i++ 뭐가더 빠를까?
물어볼 것도 없다. 당연히 ++i 가 더 빠른 것이다.
이리저리 뺑 돌아가긴 했지만, 결국 여기서 의도한 것은
가능하면 i++ 을 쓰지 말고 ++i을 써라,
어차피 후위 연산자를 사용하면, 전위 연산자를 지나칠 수 밖에 없기 때문이다.