Programming Language/C++

[C++] 연산자 오버로딩

lumana 2024. 2. 4. 08:12

연산자 오버로딩


연산자 오버로딩이란?

  • 프로그래밍 언어에서 기존에 정의된 연산자를 사용자가 직접 정의한 데이터 타입이나 클래스에 대해 재정의하는 것

  • 메서드 이름 형식 : "(operator)(연산자)"

  • 메서드 이름을 통해 함수를 직접 호출할 필요 없이 연산자 만으로 호출할 수 있다.

  • 다른 클래스에 속하는 객체 간의 연산의 경우에도 가능하다

    • v1이라는 벡터가 있을 때, v1 * 1.6 은 멤버 연산자를 통해 연산자 오버로딩이 가능

    • v2이라는 벡터가 있을 때, 1.6 * v1 은 벡터 클래스에 속하지 않는 비멤버 연산자를 통해 연산자 오버로딩이 가능

  • ex) 벡터의 합을 구할 때 덧셈, 뺄셈, 나눗셈, 곱셈(스칼라)을 사용자가 직접 정의함

      class Vector2 {
      public:
          // Vector2() : x(0), y(0) {}
          Vector2();
          // Vector2(float x, float y) : x(x), y(y) {}
          Vector2(float x, float y);
          // get함수는 const로 선언하는 것이 좋음
          // float GetX() const { return x; }
          float GetX() const;
    
          // float GetY() const { return y; }
          float GetY() const;
    
          // 멤버 연산자
          Vector2 operator+(Vector2 rhs) const;      // 프로토타입
          Vector2 operator-(Vector2 rhs) const;      // 프로토타입
          Vector2 operator*(const float rhs) const;  // 프로토타입(벡터에 실수 곱하는 함수)
          Vector2 operator/(const float rhs) const;  // 프로토타입(벡터에 실수 나누는 함수)
          float operator*(Vector2 rhs) const;        // 연산자 오버로딩
                                                  /*
                                                      return Vector2(x + rhs.x, y + rhs.y);
                                                      // rhs.GetX()를 사용 안해도 된다.
                                                      // 참조 : https://blog.naver.com/PostView.naver?blogId=tipsware&logNo=221667799577
                                                  */
    
      private:
          float x;
          float y;
      };
    
      Vector2::Vector2() : x(0), y(0) {}
      Vector2::Vector2(float x, float y) : x(x), y(y) {}
    
      float Vector2::GetX() const { return x; }
      float Vector2::GetY() const { return y; }
    
      // 비 멤버연산자
      // 멤버 메서드가 아니므로 const로 함수를 선언하지 않는다
      Vector2 operator*(const float a, const Vector2 b) {  // ex) 1,6 * Vector2typeclass
          return Vector2(a * b.GetX(), a * b.GetY());      // 전역함수라 get 함수 사용.
      }
    
      // 멤버연산자
      Vector2 Vector2::operator+(const Vector2 rhs) const {
          return Vector2(x + rhs.x, y + rhs.y);
      }
      Vector2 Vector2::operator-(const Vector2 rhs) const {
          return Vector2(x - rhs.x, y - rhs.y);
      }
      Vector2 Vector2::operator*(const float rhs) const {  // ex) Vector2typeclass * 1.6
          return Vector2(x * rhs, y * rhs);
      }
      Vector2 Vector2::operator/(const float rhs) const {
          return Vector2(x / rhs, y / rhs);
      }
      float Vector2::operator*(const Vector2 rhs) const {  // Vector의 스칼라 곱. Vector 각 성분끼리 곱의 합.
          return x * rhs.x + y * rhs.y;
      }
    
      int main(void) {
          Vector2 a(2, 3);
          Vector2 b(-1, 4);
          cout << a.GetX() << " , " << a.GetY() << '\n';
          cout << b.GetX() << " , " << b.GetY() << '\n';
          Vector2 c = a - b;
          Vector2 c1 = a + b;
          /* c1과 동일한 결과
          Vector2 d1 = a.operator+(b);
          Vector2 d2 = Sum(a, b); // "Sum 함수 --> 멤버 메서드의 활용 참고"
           */
          Vector2 c2 = a * 1.6;  // 비멤버 연산자가 없다면 1.6 * a는 에러 발생
          Vector2 c3 = a / 2;
          float c4 = a * b;
          Vector2 c5 = 1.6 * a; // 비멤버 연산자
          cout << c.GetX() << " , " << c.GetY() << '\n';
          cout << c1.GetX() << " , " << c1.GetY() << '\n';
          cout << c2.GetX() << " , " << c2.GetY() << '\n';
          cout << c3.GetX() << " , " << c3.GetY() << '\n';
          cout << c4 << '\n';
          cout << c5.GetX() << " , " << c5.GetY() << '\n';
      }
    • Vector2 Add(Vector2 rhs) --> Vector2 operator+(Vector2 rhs)

      • 멤버 연산자

      • Vector2 c1 = a + b 로 호출 가능

    • Vector2 operator*(const float a, const Vector2 b)

      • 비멤버 연산자

      • Vector2 c5 = 1.6 * b 로 호출 가능

참조) 두들낙서 C/C++ 강좌