프로그래밍/c++

연산자 오버로딩

오늘의논리 2023. 3. 1. 11:30
728x90

Position 이라는 class가 있다고 가정했을때

int main()
{
    Position pos;

    pos._x = 0;
    pos._y = 0;



    Position pos2;

    pos._x = 1;
    pos._y = 1;
    
    Position pos3 = pos + pos2;

	return 0;
}

이렇게 할경우 연산자가 적용되지 않음

연산자의 오버로딩?

일단[연산자 함수]를 정의해야함

함수도 멤버함수 vs 전역함수가 존재하는것처럼, 연산자 함수도 두가지 방식으로 만들 수 있음

* 멤버 연산자 함수 version

 

class Position
{

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

    	return pos;
    }

public:

    int _x;
    int _y;

};

 

이렇게하면

Position pos3 = pos + pos2;

가능하고

pos3. = pos.operator+(pos2);

가능

 

 a op b 형태에서 왼쪽으로 기준으로 실행됨 (a가 클래스여야 가능.a' 기준 피연산자'라고함)

 한계) a 가 클래스가 아니면 사용하지 못함(왼쪽에 클래스가 아닌 게 오게되면 안됨)

pos3+1; 되지만 1+pos 등이 되지 않음

 

그렇기때문에 전역 연산자 사용

 

* 전역 연산자 함수 version

 a op b 형태라면, a,b 모두를 연산자 함수의 피연산자로 만들어준다

 

class Position
{
public:
	Position operator+(const Position& arg)
    {
        Position pos;
        pos._x = _x + arg._x;
        pos._y = _y + arg._y;

        return pos;
    }



public:
    int _x;
    int _y;

};


Position operator+(int a, const Position& b)
{
    Position ret;
    ret._x = b._x + a;
    ret._y = b._y + a;

    return ret;
}

 

 

이런식으로 operator 밖으로 빼서 만들어 주어

1+ pos3 등을 성립시킬수 있음

 

bool isSame = (pos3 == pos4) 이것을 함수로 만들어본다면(멤버연산자함수)

 

class Position
{
    public:
    bool operator==(const Position& arg)
    {
        return _x == arg._x && _y == arg._y;
    }

public:
    int _x;
    int _y;

};

이런식으로 만들어볼수 있을것이다.

 

그럼 무엇이 더 좋은가? 그런건 없다. 심지어 둘 중 하나만 지원하는 경우도 있기 때문.

 - 대표적으로 대입 연산자( a= b)는 전역 연산자 version 으로는 못만들기 때문

 

추가로 void 형식으로 연산자 함수를 만들면 반환이 어렵기때문에 본인클래스의 참조를 반환하는식으로 만드는것이 좋다

 

Position& operator=(int arg)
{
    _x = arg;
    _y = arg

	return *this;	
}

 

* 복사 대입 연산자

대입 연산자 중, 자기 자신의 참조 타입을 인자로 받는것.

복사생성자, 복사 대입 연산자 등 특별대우를 받는 이유는

말그대로 객체가 '복사' 되길 원하는 특징 때문

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

    return *this;

}

 

기타

  • 모든 연산자를 다 오버로딩 할 수 있는 것은 아니다(::. . .* 이런건 안됨)
  • 모든 연산자가 다 2개 항이 있는것은 아님. ++, -- 가 대표적(단항 연산자)
  • 증감 연산자 ++, --
  • 전위형(++a) operator++();
  • 후위형(a++) operator++(int);

 

728x90