상세 컨텐츠

본문 제목

C++ 전역 연산자 함수

C++/C++98

by deulee 2023. 8. 5. 16:18

본문

전역 연산자 함수

 

이 전에는 연산자 오버로딩을 멤버 함수로 만드는 방법을 소개했고 이번에는 전역 연산자 함수를 만드는 것을 소개하도록 하겠다.

 

전역 연산자 함수는 말 그대로 전역 함수인데 연산자를 오버로딩하며 클래스의 외부에 존재하며 클래스의 객체를 받아들인다.

 

#include <iostream>

class Num
{
	friend const Num operator+(const Num&, const Num&);
private:
	int x;
public:
	Num() {}
	Num(int _x) : x(_x)
	{}
	// const Num operator+(const Num& right) const
	// {
	// 	return Num(x + right.x);
	// }
	void outNum(void)
	{
		std::cout << x << std::endl;
	}
};

const Num operator+(const Num& n1, const Num& n2)
{
	return Num(n1.x + n2.x);
}

int main(void)
{
	Num A(3), B(4);

	Num C = A + B + A;
	C.outNum();
	A.outNum();
	B.outNum();
	return 0;
}

 

위의 예제를 보면 실행 결과는 완전히 동일하다.

 

여기서 눈여겨 볼 점은 class 내부에서 함수를 friend지정했다는 것이다. 이 말은 이 함수는 객체끼리 덧셈을 하기 위해 모든 멤버를 자유롭게 읽을 수 있어야 한다.

 

그럼 멤버 연산자 오버로딩과 전역 연산자 오버로딩의 차이점은 뭘까?

 

바로 함수의 원형차이가 있다는 것이다.

 

1. 멤버 연산자 함수 - A.operator+(B)

 

2. 전역 연산자 함수 - operator+(A, B);

 

우선 인수의 개수가 완전히 다르다는 것을 볼 수 있다.

 

그리고 이 함수는 전역함수이기 때문에 this가 존재하지 않는다.

 

인수의 개수가 다르다는 것은 다른 형태로도 변형이 가능하다는 건데 이것은 객체와 기본형의 연산을 할 때도 이용된다.

 

기본형과의 연산

아래의 예시를 보도록 하자.

const Num operator+(int s) const
{
	return Num(x + s);
}

B = A + 3;
B = A.operator+(3);

B = 3 + A; // 불가능

 

멤버 함수에 operator+를 저렇게 오버로딩을 하게 된다면 A + 3과 같이 기본 연산자하고도 더할 수 있다.

 

왜냐하면 사실 A.operator+(3)과 같기 때문이다.

 

하지만 B = 3 + A는 어떻게 해결할까?

 

순서상으로 3.operator+(A)가 되어야 할 것 같지만 기본형의 사칙연산 오버로딩은 컴파일 단계에서 막혀있다.

 

즉, 멤버 연산 오버로딩으로는 힘들어 보인다.

 

이때 사용하는 것이 전역 연산자 함수를 이용하는 것이다.

 

class Num
{
	friend const Num operator+(int s, const Num&);
private:
	int x;
public:
	Num() {}
	Num(int _x) : x(_x)
	{}
};


const Num operator+(int s, const Num& n)
{
	return Num(s + n.x);
}

3 + A; // 가능

 

근데 굳이 이렇게 하지 않고 우회하는 방법도 있기는 하다.

 

// 전역 함수에서 멤버 연산자로 우회하기
const Num operator+(int s, const Num& n)
{
	return n + s;
}

// 멤버 연산자 함수가 전역 연산자 함수로 중계하기
const Num operator+(int s) const
{
	return s + *this;
}

 

이렇게 우회하는 이유는 코드의 불필요한 중복을 막기 위해서도 있다.

 

요약하자면 타입이 다른 객체끼리 연산할 때는 교환 법칙이 성립할 수 있도록 전역 연산자 함수를 제공해야 하며 이 함수가 객체 내부의 멤버를 읽을 수 있도록 프렌드 선언을 적절히 활용해야 한다.

 

출처

http://www.soen.kr/lecture/ccpp/cpplec.htm

 

C/C++ 강좌

 

www.soen.kr

 

'C++ > C++98' 카테고리의 다른 글

C++ 상속  (0) 2023.08.07
C++ 다양한 연산자 오버로딩의 예시  (0) 2023.08.05
C++ 연산자 함수  (0) 2023.08.05
C++ 상수 멤버, const  (0) 2023.08.05
C++ 정적 멤버, static  (0) 2023.08.05

관련글 더보기