프로그래밍 언어/C++

[게임 프로그래머 입문 올인원] 객체지향 : 연산자 오버로딩 (32강)

순정법사 2023.09.12

D. 연산자 오버로딩

1. 연산자 오버로딩의 기초

a. 연산자 오버로딩이란?

🌟 기존 연산자를 사용자 정의 클래스나 데이터 형식에 대해 재정의하여 새로운 동작을 정의하는 것을 의미

 

  • 사용자 정의 객체끼리 연산자를 사용하거나, 사용자 정의 데이터 형식에 기본 연산자를 적용
  • 사용자 정의 클래스의 편의성과 가독성을 높이는 데 사용
  • 사용자 정의 데이터 형식에 대한 다양한 연산을 지원하는 데 유용

 

b. 멤버 연산자의 함수 버전

  • a op b 형태에서 왼쪽을 기준으로 실행 
  • a가 class여야만 함 (반대의 경우 에러)
  • 매개변수는 아무값이나 가능
  • 이름은 'operator연산자' 로생성, 연산자는 연산하려는 연산자로 사용

 

⏳ 예제 : 멤버 연산자의 함수

class Pos{
public : 
    클래스이름 operator+(const 클래스이름& b)
    {
		Pos pos;
        pos.x = x + b.x;
        pos.y = y + b.y;
        return pos;
    }
    
    ...
};

int main(){
	Pos Pos1;
    Pos Pos2;
    
    Pos pos3 = pos1 + pos2
    //pos3 = pos1.operator+(pos2);
}

 

c. 전역 연산자 함수 버전

a op b 형태라면, a/b 모두를 연산자 함수의 피연산자로 사용 

 

⏳ 예제 : 전역 연산자 함수

Pos operator+(int a, const Pos& b){
	Pos pos;
    pos.x = a+b.x;
    pos.y = a+b.y;
    return pos;
}

 

 

2. 연산자 오버로딩 심화

a. 연산자 지원 범위

다양한 연산자를 지원함. 아래는 ==연산자를 사용하는 예시

 

⏳ 예제 : 객체가 동일한지 보는 멤버 함수 연산자

class Pos{
public : 
...

    bool operator==(const Pos& b)
    {
		return x == b.x && y == b.x;
    }
    
...
}

 

b. 연산자 오버로딩과 생성자

객체를 생성하면서 대입 연산자를 사용하게 되면

연산자 오버로딩을 사용한 대입 연산자를 실행하는게 아닌 생성자를 부르는용도로 사용됨

 

⏳ 예제 : 생성자와 대입 연산자

#include <iostream>
using namespace std;

class Pos {
public:
    //생성자
    Pos(int a) {
        x = a;
        y = a;
    }

    //대입 연산자
    void operator=(int b)
    {
        x = b;
        y = b;
    }

public:
    int x = 0;
    int y = 0;
};

int main() {
    //생성자
    Pos pos1(10);	//이 코드와 아래 코드는 동일하게 생성자를 실행
    Pos pos2 = 10;	//연산자 오버로딩 X

    //대입 연산자
    pos1 = 10;
    pos2 = 20;
}

 

만약 위 대입연산자가 없다고 가정해도, 아래 pos1, pos2는 실행됨

이유는 생성자가 저 코드를 처리하고 있기 때문

 

심지어 아래 코드처럼 다른 함수를 생성한 후 실행해도, 생성자가 간접적으로 자동으로 대입해서 실행됨

 

void TestPos(Pos a){}

int main(){
	TestPos(10); 	//Pos(int a)가 실행됨 
}

 

c. explicit 키워드

따라서 explicit 키워드를 사용해서 

인자 하나로 생성자를 만드는 경우에 컴파일러가 자동으로 생성자에 대입하지 않도록 해야함!!

 

🌟 즉, 객체의 자동 형 변환이나 암시적 변환을 방지하고, 명시적인 형 변환을 강제화하는 키워드 

 

⏳ 예제 : explicit 키워드로 오류를 막은 모습

#include <iostream>
using namespace std;

class Pos {
public:
    //생성자
    explicit Pos(int a) {
        x = a;
        y = a;
    }

    //대입 연산자
    void operator=(int b)
    {
        x = b;
        y = b;
    }

public:
    int x = 0;
    int y = 0;
};

void TestPos(Pos a){}

int main() {
	TestPos(10); 	//error
    
   	Pos pos1(10) 
    Pos pos2 = 20	//error

    //대입 연산자
    pos1 = 10;	//error
    pos2 = 20;	//error
}

 

d. 자기 자신에 대한 참조를 뱉어주는 *this

a = b = c처럼 아래와 같은 대입연산을 대입 연산자 오버로딩에 사용하고 싶다면

코드를 아래와 같이 수정해줘야 함

 

⏳ 예제 : 자기 자신에 대한 참조를 뱉어주는 *this

#include <iostream>
using namespace std;

class Pos {
public:
    //생성자
    explicit Pos(int a) {
        x = a;
        y = a;
    }

    //대입 연산자
    Pos& operator=(int b)
    {
        x = b;
        y = b;
        
        return this*	//자기 자신에 대한 참조를 뱉음
    }

public:
    int x = 0;
    int y = 0;
};


int main() {
    
   	Pos pos1(10) 
    Pos pos2;
    Pos pos3;
    
   	pos1 = pos2 = pos3 	//pos2 = pos3부터 연산 시작

}

 

 

 


출처 : https://www.inflearn.com/course/%EA%B2%8C%EC%9E%84-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8-%EC%9E%85%EB%AC%B8-%EC%98%AC%EC%9D%B8%EC%9B%90-rookiss#curriculum

 

[게임 프로그래머 입문 올인원] C++ & 자료구조/알고리즘 & STL & 게임 수학 & Windows API & 게임 서버 -

어디부터 시작할지 막막한 게임 프로그래밍 입문자를 위한 All-In-One 커리큘럼입니다. C++, 자료구조/알고리즘, STL, 게임 수학, Windows API, 게임 서버 입문으로 이어지는 알찬 커리큘럼으로 게임 프

www.inflearn.com