기존의 연산자를 우리가 정의한 클래스나 구조체에 맞게 동작하도록 재정의 하는 것을 말한다
-> 멤버함수로 정의할 것이다 (클래스 내부)
예를 들어 바로 코드를 보겠다
이 코드에서는 내가 원하는 건 box1객체와 box2객체의 box, apples변수의 값을 각각 더한 걸 출력하고 싶었다
하지만 box3객체에서 에러가 발생!
#include <iostream>
using namespace std;
class AppleBox
{
private:
int box; // 사과박스 수
int apples; // 사과의 수
public:
AppleBox(int Box, int Apples)
{
box = Box;
apples = Apples;
}
};
int main()
{
AppleBox box1(10,5);
AppleBox box2(5,10);
AppleBox box3 = box1 + box2;
}


여기서 box1 + box2를 구현하려면 클래스 내부에 연산자 오버로딩을 정의해주어야한다
-> 현재 << 연산자를 배우지 않았기 때문에 클래스 내부에 출력함수를 따로 만들어두었다
출력함수에 const를 사용한 이유
: 이 함수는 객체의 멤버 변수를 변경하지 않겠다는 뜻
즉, box와 apples변수는 값이 변경되지 않고 반환하겠다는 뜻임


#include <iostream>
using namespace std;
class AppleBox
{
private:
int box; // 사과박스 수
int apples; // 사과의 수
public:
AppleBox(int Box, int Apples)
{
box = Box;
apples = Apples;
}
AppleBox operator + (const AppleBox& other)
{
return AppleBox(box + other.box, apples + other.apples);
}
void print() const
{
cout << "박스 수: " << box << ", 사과 수: " << apples << endl;
}
};
int main()
{
AppleBox box1(10,5);
AppleBox box2(5,10);
AppleBox box3 = box1 + box2;
box3.print();
}
출력값:
#include <iostream>
using namespace std;
class Point
{
private:
int x;
int y;
public:
Point(int _x = 0, int _y = 0) : x(_x), y(_y) { }
void Print() const
{
cout << x << ',' << y << endl;
}
const Point operator + (const Point& arg)
{
Point pt;
pt.x = this->x + arg.x;
pt.y = this->y + arg.y;
return pt;
}
};
int main()
{
Point p1(2, 3), p2(5, 5);
Point p3;
p3 = p1 + p2;
p3.Print();
p3 = p1.operator+(p2);
p3.Print();
return 0;
}
출력값:
단항연산자란?
- & ~ + - ++ -- 와 같이 피연산자를 하나만 사용하는 연산자를 말한다
- 부호연산자(+, -), 증감연산자(++, --), 논리 부정 연산자(!) 등이 포함
- ++ 연산자와 -- 연산자를 전위와 후위를 통해 알아보겠다
클래스 내부에 연산에 사용될 x, y 변수를 선언해주고 생성자 초기화 리스트를 이용하여 초기값 0으로 지정
전위증가는 operator++ ( ) 함수
-> 전위증가는 값을 증가하고 바로 현재 객체(해당 클래스를 참조하는 객체)를 참조하는 형태로 반환한다 -> return * this
후위증가는 operator++ (int) 함수
-> 증가하기 전의 값을 반환할 객체 생성 후 이 객체를 반환하고 클래스 내부의 변수의 값은 증가시켜둔 상태
#include <iostream>
using namespace std;
class Point
{
private:
int x;
int y;
public:
Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
void Print() const
{
cout << x << ',' << y << endl;
}
const Point& operator++ ()
{
++x;
++y;
return *this;
}
const Point& operator++(int)
{
Point pt(x, y);
++x;
++y;
return pt;
}
};
int main()
{
Point point1(2, 3);
Point point2(2, 3);
Point result;
result = ++point1; // 전위 증가
point1.Print();
result.Print();
result = point2++; // 후위 증가
point2.Print();
result.Print();
return 0;
}

#include <iostream>
using namespace std;
class Point
{
private:
int x;
int y;
public:
Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
void Print() const
{
cout << x << ',' << y << endl;
}
const Point& operator-- ()
{
--x;
--y;
return *this;
}
const Point& operator--(int)
{
Point pt(x, y);
--x;
--y;
return pt;
}
};
int main()
{
Point point1(2, 3);
Point point2(2, 3);
Point result;
result = --point1; // 전위 증가
point1.Print();
result.Print();
result = point2--; // 후위 증가
point2.Print();
result.Print();
return 0;
}
결과값:
이항연산자란?
피연산자가 2개인 연산자
산술연산자(+, -, *, /), 문자열 결합 연산자(+), 비교연산자(<, >), 논리연산자(&&, ||), 대입연산자(==, -=, +=) 등이 포함된다
#include <iostream>
using namespace std;
class Point
{
private:
int x;
int y;
public:
Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
void Print()
{
cout << x << ',' << y << endl;
}
bool operator == (const Point& arg) const
{
return x == arg.x && y == arg.y ? true : false;
}
};
int main()
{
Point p1(2, 3), p2(5, 5), p3(2, 3);
if (p1 == p2)
{
cout << "p1 == p2입니다" << endl;
}
if (p1 == p3)
{
cout << "p1 == p3입니다" << endl;
}
return 0;
}



#include <iostream>
using namespace std;
class Point
{
private:
int x;
int y;
public:
Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
void Print()
{
cout << x << ',' << y << endl;
}
bool operator == (const Point& arg) const
{
return x == arg.x && y == arg.y ? true : false;
}
bool operator != (const Point& arg) const
{
return !(*this == arg);
}
};
int main()
{
Point p1(2, 3), p2(5, 5), p3(2, 3);
if (p1 != p2)
{
cout << "p1 != p2입니다" << endl;
}
if (p1 != p3)
{
cout << "p1 != p3입니다" << endl;
}
return 0;
}

위에서 작성한 연산자 오버로딩들의 예시는 모두 멤버함수로 구현하였다
하지만 멤버함수로 작성하였을 때 동작이 안되는 경우도 있는데 이럴때는 전역함수로 연산자 오버로딩을 구현해주어야 한다! (클래스 외부)
(왼쪽 피연산자가 해당 클래스의 객체가 아닐 경우를 의미)
ex) k + p1 을 연산하는 경우
class Point
{
---
}
int main()
{
Point p1(2,3);
Point p2(1,3);
int k;
p1 + p2;
k + p1;
return 0;
}
ex) p3 = p1 - p2를 연산하는 경우
#include <iostream>
using namespace std;
class Point
{
private:
int x;
int y;
public:
Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
void Print()
{
cout << x << ',' << y << endl;
}
int GetX() const
{
return x;
}
int GetY() const
{
return y;
}
};
// 전역함수
const Point operator - (const Point& argL, const Point& argR)
{
return Point(argL.GetX() - argR.GetX(), argL.GetY() - argR.GetY());
}
int main()
{
Point p1(2, 3), p2(5, 5);
Point p3;
p3 = p1 - p2;
p3.Print();
return 0;
}
연산자 오버로딩을 전역함수로 선언한다
인자로 메인함수에서 p1과 p2를 받아온다
해당 클래스의 GetterX, GetterY함수로 접근하여 private로 선언해둔 x, y 변수에 접근한다
-> GetX( ), GetY( ) 함수 말고 friend함수를 사용하는 것도 가능하다
서로의 클래스 객체의 값을 연산하여 반환

특정 상황에서 클래스 내에 접근하지 못하도록 private로 접근 제한을 두었는데, 필요의 경우 해당 클래스나 함수에서 접근 가능하도록 사용하는 함수
프렌드 함수는 캡슐화를 저해하므로 가능하면 위에서 사용한 Get,Set함수를 사용한다!
ex) Point 클래스 내부에 전역함수를 friend로 지정
-> 인자로 들어온 argL와 argR는 해당 클래스의 x변수와 y변수에 바로 접근이 가능해진다

함수 호출 연산자란?
객체를 함수처럼 호출할 수 있게 하는 기능이다
클래스에 operator( )를 정의하면 그 클래스의 객체를 함수처럼 호출이 가능하다
생김새는 함수가 아니지만 기능이 함수와 같은 역할 느낌
ex) Adder 클래스를 생성하고 생성자 초기화 리스트로 인자로 받아온 값을 value로 지정
메인함수에 작성한 Adder adder객체를 함수 객체라고 한다
#include <iostream>
using namespace std;
class Adder {
private:
int value;
public:
Adder(int init) : value(init) {}
int operator()(int x) {
value += x;
return value;
}
};
int main() {
Adder adder(10); // 초기 값 10
cout << adder(5) << endl; // 15 출력
cout << adder(10) << endl; // 25 출력
return 0;
}
함수는 아니지만 클래스 내부에 operator( ) 선언
-> 메인함수에서 클래스의 객체를 생성한 뒤 함수에 접근하지 않고 바로 객체를 함수처럼 사용 가능하다!
-> 위의 코드를 보면 메인함수에서 객체에 바로 매개변수를 넣어 함수처럼 사용중!
-> 직관적으로 볼 수 있어서 편하다

operator( )가 아닌 기존 함수처럼 사용했더라면
-> 클래스 내부에 int add함수를 정의해두고 메인함수에서 객체를 생성한 뒤 객체로 접근해서 함수를 호출해야한다

임시객체로도 사용이 가능하다
임시객체란?
잠깐 생성되었다가 한번 쓰이고 바로 소멸되는 객체를 말한다
쉽게 말하자면, 객체의 이름을 정하지 않고 바로 생성해서 사용하는 객체를 뜻한다 (잠깐 쓰고 버리는 용도 - 자동소멸)
위의 코드처럼 
클래스의 객체 이름을 생성해서 사용해도 된다
-> 이렇게 사용할 경우 객체가 명확히 존재하기 때문에 재사용이 가능하다
