About 연산자 함수
연산자함수
어떤 클래스의 두 객체를 선언했다고 생각해보자.
기본적으로 객체끼리의 연산은 불가능하다.
(ex)Rectangle1 + Rectangle2 = ??? //불가능
하지만 클래스 내부에 연산자함수를 정의해준다면 이러한 연산이 가능해진다.
정사각형을 두개 더한다고 생각해보자.
사람들마다 정사각형을 더했다! 라고 생각하는 값이 다를 것이다.
어떤사람은 "합한 결과는 마름모다" 라고 생각할 수도 있고,
어떤사람은 "합한 결과는 두 정사각형의 변의길이의 합이다" 라고도 할 수도 있겠다.
이렇게 사람마다 다르기 때문에 컴파일러 자체에서도 연산자를 자동생성하지 않는다.
대신 클래스 내부안에 +연산을 '두 객체의 변의 길이의 합을 변의 길이로 하는 정사각형'
이라고 정의를 내린다면 , 그때부터 그 규칙에 의해 연산이 가능하다.
변의길이가 9인 정사각형c =변의길이4 정사각형a + 변의길이5 정사각형b
이런식으로 말이다.
물론, 따로 멤버함수를 정의해서 같은 연산을 할수있겠지만..
a.plus(b) 보다 a+b가 가독성이 높은건 사실이다.
정의
형을 유지한 체 정보만 연산하는 것이 핵심이다.
정사각형 두개를 더한다고 생각하면, 정사각형이라는 형태는 유지하지만
변의 길이라는 정보는 연산이 되어야한다.
이런 규칙으로 만들어야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
class Rectangle
{
public:
Rectangle operator+(const Rectangle &rhs)
{
int LengthSum = this->m_nLength + rhs.GetLength();
Rectangle result(LengthSum);
return result;
}
private:
int m_nLength;
}
|
연산자 함수의 선언과 정의를 자세히 관찰해야한다.
반환값은 Rectangle이다.(형을 유지했다.)
매개변수는 Rectangle의 참조형이다(불필요한 객체생성을 막아 최적화시켰다.)
정의에서는 새로운 객체를 하나 생성하였다.
굳이 왜 새로운걸 만들어서 메모리를 사용하는 것일까?
생각해보자. a = b + c 에서 b와 c의 값이 변하는가?
변하지 않는다. 그렇기에 b+c의 값을 저장해줄 어떠한 공간이 필요한 것이다.
그리고 그 공간에 할당한 정보를 반환해준다.
결국 a = b + c 연산이 a = (b+c의 값을 저장한 어떤 객체) 가 되는것이다.
실제로 a에 값을 넘겨주는 객체는 b+c의 값이 저장된 이름이 없는 임시 객체이다.
여기까지 +연산을 위한 연산자 함수 정의에 대해 알아보았다.
빼기연산,곱하기연산,나누기연산 등등 여러 연산도 저런식으로 정의하고 사용하면 된다.
점이다.
그럼 a에 복사되는건 b+c가 반환한 값일까?
실제로 a에 복사되는 것은 b+c가 반환한 값을 가지고 생성된 임시객체이다.
이제 연산결과를 전달하는 =연산자에 대해 알아보자
a에 b의 정보를 전달하겠다는 말은 결국엔 a에 b의 값을 복사하여 넣겠다는 소리다.
이때 깊은복사와 얕은복사를 잘따져야한다.
=을 사용하는 경우를 생각해보면 2가지이다.
1) a = b; //b의 값을 a에 깊은복사한다.
2) a = b+c; //b+c의 결과값을 갖는 임시객체의 값을 a에 얕은 복사한다.
왜 임시객체에 대해 얕은복사를 해야할까? 깊은 복사를 한다고 에러가 뜨는게 아니다.
그러나 복사후 사라질 임시객체에 대해 깊은복사를 하게 되면 쓸데없이 메모리를 사용
하게 된다.
1
2
3
4
5
6
7
8
9
10
11
|
class Rectangle
{
public:
Rectangle& operator=(const Rectangle &rhs)
{
this->m_nLength = rhs.m_nLength;
return *this;
}
private:
int m_nLength;
}
|
사실 지금 쓰는 Rectangle class는 깊은복사 얕은복사가 의미가 없다.
메모리할당도 안할뿐더러 포인터도 없기 때문이다.
일단 =연산자 함수를 자세히 보면 반환형,매개변수형이 참조형이다.
매개변수형은 누구나 이해할수 있지만, 반환형이 클래스참조형이라니 이해가 안갈수 있다.
가령 a = b = c ;를 연산할때 반환형이 void라면 문제가 생길것이다.
a = 값이없음 ;
이런 경우를 위해서 클래스참조형으로 반환해준다면
a = b = c ; 에서 a = b(c의값이 대입된) ; 이 되고, a(c의값이 대입된 b의 값이 대입됨)가
된다.
댓글
댓글 쓰기