1. 연산자 오버로딩

클래스를 이용하여 두 개의 객체를 만들었을때 두 객체 사이의 연산이 가능할까?

class Position
{

public:
    int _x;
    int _y;
};


int main()
{
    Position pos;
    pos._x = 0;
    pos._y = 0;

    Position pos2;
    pos2._x = 1;
    pos2._y = 1;

    Position pos3 = pos + pos2;

    return 0;
}

위와 같은 연산을 하면 오류를 뿜는 것을 알 수 있다.

먼저 연산자 함수를 정의한다. 연산자 함수는 둘을 연산하도록 하는 함수이다.

 

(1) 멤버 연산자 함수

class Position
{
public:

    Position operator+(const Position& arg)
    {
        Position pos;
        pos._x = _x + arg._x;
        pos._y = _y + arg._y;
    }


public:
    int _x;
    int _y;
};

a op b 형태에서 왼쪽을 기준으로 실행된다.

a가 클래스여야 가능하다. 이 때 a는 '기준 피연산자'라고 한다.

이번에는 클래스에 int형 연산을 할 수 있도록 오버로딩 해보면

	//~~
	Position operator+(int arg)
    {
        Position pos;
        pos._x = _x + arg;
        pos._y = _y + arg;
    }
    //~~
    int main()
{
    Position pos;
    pos._x = 0;
    pos._y = 0;

    Position pos2;
    pos2._x = 1;
    pos2._y = 1;

    Position pos3 = pos + pos2;
    Position pos4 = pos3 + 1;

    return 0;
}

연산은 잘 되나

Position pos4 = 1 + pos3;

위치를 서로 바꾸면 오류가 발생하게 된다.

 

(2) 전역 연산자 함수

이 문제를 해결하기 위해 전역 연산자 함수에서는 a op b 형태에서 a와 b 모두를 피연산자로 만들 수 있다.

클래스 외부에서 만들면

Position operator+(int a, const Position& b)
{
    Position ret;

    ret._x = b._x + a;
    ret._y = b._y + a;

    return ret;
}

위치를 서로 바꿔도 오류가 발생하지 않게 된다.

 

2. 다른 연산자 함수를 만들기

 

(1) 서로 같은지 판별하는 연산자

    bool operator==(const Position& ret)
    {
        return _x == ret._x && _y == ret._y;
    }

클래스 내부에서 생성한다.

 

(2) 대입 연산자

    Position operator=(int a)
    {
        _x = a;
        _y = a;

        return *this;   // 이 포인터의 주소를 반환
    }

클래스 내부에서 생성한다.

 

(3) 복사 대입 연산자

자기 자신의 참조 타입을 인자로 받는 대입 연산자이다.

    Position& operator=(Position& a)
    {
        _x = a._x;
        _y = a._y;

        return *this;   // 이 포인터의 주소의 값을 반환
    }

객체가 복사되도록 한다.

 

 

 

3. 주의점

멤버 함수 연산자와 전역 함수 연산자를 사용할 때 각 함수 연산자에서 선언이 불가능한 것들이 있다.

아래는 오버로딩 불가능한 연산자들이다.

 

- 오버로딩이 불가능한 연산자들

(1) 멤버 함수 연산자

 

(2) 전역 함수 연산자

- 대입('=') : 피연산자로 보통 함수가 오고, 정수가 좌측에 온다는 것은 위험함.

 

(3) ' :: ' 또는 ' . '

 

4. 기타

(1) 증감연산자

전위형(++a)는 operator++() { }

후위형(a++)는 operator++(int) { }

의 형태로 만든다.

Position& operator++() // 전위형에서 ++을 연속적으로 호출할 때 올바르게 작동하도록 한다
{
	_x++;
	_y++;
}

void operator++(int)
{
	_x++;
	_y++;
}
    Position pos5;
    pos3 = (pos5 = 5);

    
    pos5 = pos3++;

위와 같이 코드를 작성하면 문제가 발생하는데 이는 반환 타입 미스매치로 인한 오류이다.

    Position& operator=(Position& a)
    {
        _x = a._x;
        _y = a._y;

        return *this;   // 이 포인터의 주소를 반환
    }

위의 코드에 의해 pos3 = (pos5 = 5); 에서 값을 pos&를 반환하게 되는데.

(pos&) = (pos) 의 형식이 되어 타입이 맞지 않아 오류가 발생하게 된다.

이 때에는 위의 코드를 수정하여 const를 붙여주면 된다.

    Position& operator=(const Position& a)
    {
        _x = a._x;
        _y = a._y;

        return *this;   // 이 포인터의 주소를 반환
    }

 

'기초 C++ 스터디 > 객체지향' 카테고리의 다른 글

6-1. 동적 할당  (0) 2023.05.31
5-7. 객체지향 정리  (0) 2023.05.30
5-5. 초기화 리스트  (0) 2023.05.26
5-4. 다형성  (0) 2023.05.26
5-3. 은닉성  (0) 2023.05.26