본문 바로가기

Programming/C / C++

[C++] 연산자 오버로딩 - 교환법칙의 성립과 임시객체(Temporary Object)

 교환 법칙?  
 3 + 2 라는 연산이 있다. 여기에서 피연산자 위치를 다르게 바꿔도 ( 2 + 3 ) 동일한 결과를 가져오게 하는 법칙이 바로 교환법칙이다. 우리는 연산자 오버로딩을 사용함에 있어서 이렇게 교환법칙도 성립할 수 있게 만들어야 한다. 아래의 연산자 오버로딩을 보자.
 23번째 라인의 Point p2=p1+3; 이 문장은 C++에서는 p1.operator+( 3 ) 이와 같이 인식되는것을 우리는 앞서 알아봤었다. 교환법칙이 성립되려고 하면 다음과 같이 써도 에러가 나지 않아야 한다. 
 하지만 실제로 저 부분을 소스코드에 집어 넣고 컴파일 해보면 에러가 생기는 것을 알 수 있다. 
(Visual Studio 2010에서는 컴파일 하지 않아도 에러를 실시간으로 잡아내는 기능이 추가 되었다)

 문제 제기  
 그럼 왜 이런 교환법칙이 성립이 안되는 것일까? 자세히 한번 알아보자. 
 여기에서 숫자 3은 int형 데이터이고,  p1은 객체이다 타입이 다르기 때문에 덧셈이 불가능 하다. 그래서 오버로딩 되어 있는 operator +함수를 호출 하게 된다. 이 operator + 함수를 호출 하기 전에 이것이 멤버 함수인지 전역함수 인지 일단 알아 볼텐데, 우리는 멤버 함수로서 정의을 했으므로, 멤버 함수에서의 객체는 무조건 왼쪽이 기준으로 operator+ 함수를 호출하므로 3.operator+ (p1) C++에서는 이러한 문장으로 인식이 될 것이다. (멤버 함수로의 오버로딩시 무조건 연산자의 왼쪽이 피연산자의 기준이 된다.)
 여기서 바로 문제가 생긴다. 숫자 3은 int형 데이터로 operator+라는 함수가 멤버로서 존재할리 없다. 이 문장은 논리적 으로 문제가 있는 것이다. 그러면 우리는 교환법칙이 성립 되도록 추가적인 코드를 만들어야 한다.

 문제 해결  
 : 우리는 멤버 함수 오버로딩으로는 문제가 있다는 것을 알았다. 그러면 전역 함수 오버로딩시에는 어떻게 될까? Point p3 = 3 + p1; 이 문장은 전역함수에서 인식될때 왼쪽에 있는 피연산자가 첫번째 인자로, 오른쪽에 피연산자가 두번째 인자로 가기 때문에 operator+ (3, p);  로 C++에서 인식되고 이것은 논리적으로 문제가 전혀 없다. 결론이 나왔다. 우리는 교환법칙을 성립 해주기 위해서 전역함수 오버로딩을 제공해주기만 하면 되는것이다. 바로 아래와 같이 말이다. 결과도 이상없이 출력되는 것을 알 수 있다.


 임시 객체  
 위와 같이 선언된 문장이 있다. 우리는 보통 생각하기에 이 문장은 int 형 데이터가 4Byte 이므로 메모리 공간에 4Byte의 메모리 공간만 할당한다고 생각하겠지만, 이 경우에 메모리 공간에 3과 4라는 상수도 CPU에 의해서 연산이 이루어 져야 하므로 메모리 공간에 올라간다. 
 그럼 이렇게 상수도 메모리 공간에 올라가니까 다음 라인에서 이 숫자를 참조가 가능할까? 불가능하다. 물론 변수 a는 참조가 가능하다. 무슨 차이가 있을까? 바로 상수3과 4는 변수 a와 같이 이름이 없기 때문이다.
 위 소스 코드는 임시 객체 생성 코드 이다. 여기에서 AAA("Temp Obj");는  AAA aaa("aaa Obj"); 와 비교해보면 무엇이 틀린지 금방 알 수 있다. 바로 AAA("Temp Obj")는 이름이 없다. 이 문장은 AAA라는 객체 클래스를 생성하는데 "Temp Obj"라는 문자열을 받는 함수를 호출하라는 의미이다. 물론 객체는 생성하지만, 이름이 없어서 해당 라인을 벗어나면 바로 소멸 된다. 이렇게 만들어지는 순간은 존재했다가 해당 라인에서 벗어나면 소멸하는 객체를 바로 임시 객체 라고 한다. 임시 객체의 생성과 소멸은 결과를 보면 충분히 이해 할 수 있을 것이다. (해당 라인에서 생성, 벗어나자마자 소멸을 cout으로 출력해주는것을 볼 수 있다.)


 이 임시객체라는 것은 경우에 따라서는 컴파일러에 따라 최적화가 되기 때문에 가급적이면 사용하는 것이 좋다. 위의 예제를 임시객체를 이용해 다음과 같이 바꿀 수도 있을 것이다.