#operator
operator를 사용하여 연산자 오버로딩을 구현 할 수 있다.
-> 함수의 오버로딩 규칙을 연산자에 적용한 것이다.
예를 들어 클래스에 멤버변수 i_a와 i_b를 만들었을 때
클래스+3;
이런식으로 선언하면
클래스에 있는 i_a에 +3을 하라는 건지 i_b에 +3을 하라는 건지 알 수 없다.
이때 operator 를 통해 해당 +연산자를 어떤식으로 어떻게 더할 것인지 정의해 줄 수 있다.
(+뿐만 아니라 ++, =+, =, -, -= 등 여러 연산을 operator로 정의해 줄 수 있다.)
#include "stdafx.h"
#include <iostream>
using namespace std;
class CLS
{
int m_iA;
int m_iB;
public:
CLS(int _iA, int _iB) :m_iA(_iA), m_iB(_iB) {}
CLS operator+(CLS& _cls) // 클래스의 덧셈에서 + 정의
{
return CLS(m_iA + _cls.m_iA, m_iB + _cls.m_iB);
}
void Func()
{
cout << "m_iA: " << m_iA << endl;
cout << "m_iB: " << m_iB << endl;
}
};
int main()
{
CLS cls(10, 20);
CLS cls2(20, 30);
cls = cls + cls2;
cls.Func();
return 0;
}
operator 는 위와 같이 쓰인다.
반환타입 operator연산자(매개변수)
{
정의
}
로 사용해주면된다.
이는 -나 = 도 전부 동일하다.
위는 매개변수로 같은 타입의 객체를 받았지만
int형을 받는거 또한 가능하다.
#include "stdafx.h"
#include <iostream>
using namespace std;
class CLS
{
int m_iA;
int m_iB;
public:
CLS(int _iA, int _iB) :m_iA(_iA), m_iB(_iB) {}
CLS operator+(int _i) // 클래스의 덧셈에서 + 정의
{
return CLS(m_iA + _i, m_iB);
}
void Func()
{
cout << "m_iA: " << m_iA << endl;
cout << "m_iB: " << m_iB << endl;
}
};
int main()
{
CLS cls(10, 20);
cls = cls + 3;
cls.Func();
return 0;
}
이러면 이때 cls+3의 값은
cls의 m_iA에 +3이 되고
Func에 의한 결과값은 13, 20이 출력되게 된다.
이때 operator+는
어떠한 방식으로 불려와 지는 것이냐면
cls+3;은
cls.operator+(3);
으로 사용되는것 이기 때문에
객체가 좌측에 있어야한다.
3+cls;로 진행 하게 될 경우 오류를 볼 수 있는데
이때 이 교환법칙을 성립시키려면 따로 구현을 해줘야한다.
교환법칙을 위해서는 연산자 오버로딩을 전역에 구현해야 한다.
-> 이때 인자중 하나는 객체타입 이거나 객체의 레퍼런스 타입이 와야한다.
CLS operator+(int _i)의 교환법칙을 위해
전역에
CLS operator+(int _i, CLS& _cls)
{
return _cls + _i;
}
이런식으로 선언해주면
3+cls;도 작동하게 된다.
#operator=
CLS& operator=(CLS& _cls)
{
m_iA = _cls.m_iA;
m_iB = _cls.m_iB;
return *this;
}
operator=의 경우 연속대입 (a=b=c)을 위해 반환타입을 해주는 것이 좋고
operator=은 함수가 종료되어도 자기 자신은 메모리에서 소멸되지 않기 때문에
연산속도를 높이기 위해서 &(레퍼런스)를 사용한다.
여기서 위처럼 대입연산자를 오버로딩 해주지 않아도 디폴트 대입연산자를 통해 대입연산이 가능하다.
객체생성 시 대입연산자는 복사생성자의 호출이다.
CLS cls2 = cls1;
객체 생성 후 사용하는 대입 연산자는 대입 연산자의 호출이다.
CLS cls2;
cls2 = cls1;
디폴트 대입 연산자는 복사 생성자 처러 얕은 복사가 이루어 질 수 있기 때문에
대입 연산자를 정의하게 되면 깊은 복사 방식으로 하는 것이 좋다.
#operator를 통한 전위증감 및 후위증감 구현
전위 증감은 (++i) 자기자신을 1증가 시키고 그것을 연산에 사용하는 것이다.
후위 증감은 (i++) 본체를 복사해두고 자기자신을 1증가 시키고 연산에는 복사시킨 (아직 1이 증가 안한)값을 사용하는 것이다.
전위증감을 구현 할 때 단항 연산 이기 때문에 매개변수는 없다.
CLS& operator++()
{
++m_iA;
++m_iB;
return *this;
}
후위증감은 전위증감과 구분 하기위해 매개변수에 int를 써준다 (매개변수는 받아온다는 뜻이 아님)
CLS operator++(int)
{
CLS Temp(*this); // 현재 값을 Temp에 복사해줌
++m_iA;
++m_iB;
return Temp; // 이때 Temp값은 사라지는 값 이므로 레퍼런스 반환을 해주지 않는다.
}
#임시객체
변수명이 없이 선언하면 코드라인에서만 잠시 메모리에 등록되었다가 사라지는것을 임시객체라고 한다.
예를들면
CLS();
이런식으로 클래스의 변수를 따로 지정하지 않고
클래스(); 로 하게되면 해당 코드라인에서 생성되었다가 코드라인이 지나가면 사라지게 된다.
이때 임시객체도 생성자의 호출에 의해 완성되기 때문에 생성자가 호출되게 된다.
'개발 Study' 카테고리의 다른 글
#35. 클래스 템플릿 (0) | 2021.05.21 |
---|---|
#34. Template 및 inline (0) | 2021.05.20 |
#32. 바인딩 (0) | 2021.05.14 |
#31. 캐스팅(형변환) (0) | 2021.05.14 |
#30. 오버라이딩, virtual, 객체포인터 (0) | 2021.05.13 |