cpp

C++ 연산자 오버로딩 (Operator Overloading)

임베디드 친구 2024. 12. 19. 20:47
반응형

C++은 객체 지향 프로그래밍 언어로, 사용자 정의 타입(클래스)을 정의할 수 있습니다. 이러한 클래스에서 연산자를 사용자 정의 타입에 맞게 동작하도록 오버로딩(overloading)할 수 있습니다. 연산자 오버로딩을 활용하면 직관적이고 간결한 코드를 작성할 수 있으며, 객체 간의 연산을 정의하거나 확장할 수 있습니다.

이 글에서는 C++의 연산자 오버로딩에 대해 설명하고, 예제를 통해 이를 구현하는 방법을 알아보겠습니다.

연산자 오버로딩이란?

연산자 오버로딩은 C++에서 제공하는 연산자를 사용자 정의 클래스에서 사용할 수 있도록 재정의하는 기능입니다. 예를 들어, +, -, *, /, ==와 같은 연산자를 클래스의 동작에 맞게 정의할 수 있습니다.

연산자 오버로딩의 특징

  1. 기존 연산자의 의미 확장: 기존 연산자를 사용자 정의 타입에 맞게 동작하도록 재정의합니다.
  2. 가독성 향상: 연산자를 활용하여 코드의 가독성을 높일 수 있습니다.
  3. 멤버 함수와 비멤버 함수로 구현 가능: 연산자는 멤버 함수 또는 비멤버 함수로 구현할 수 있습니다.

주의: 연산자 오버로딩은 새로운 연산자를 생성하는 것이 아니라, 기존의 연산자를 확장하는 것입니다. 또한, C++에서 일부 연산자는 오버로딩할 수 없습니다.

오버로딩 가능한 연산자

C++에서 오버로딩 가능한 연산자는 다음과 같습니다.

  • 산술 연산자: +, -, *, /, %
  • 비교 연산자: ==, !=, <, >, <=, >=
  • 논리 연산자: &&, ||, !
  • 비트 연산자: &, |, ^, ~, <<, >>
  • 기타 연산자: [], (), ->, =

연산자 오버로딩 구현하기

기본 구조

연산자 오버로딩은 클래스의 멤버 함수 또는 비멤버 함수로 구현됩니다. 구현 방식은 다음과 같습니다:

  • 멤버 함수로 구현할 경우: 좌측 피연산자가 클래스 객체입니다.
  • 비멤버 함수로 구현할 경우: 좌측 피연산자가 클래스 객체가 아닌 경우에도 동작 가능합니다.

예제: 복소수 클래스에 + 연산자 오버로딩하기

다음은 복소수(Complex Number) 클래스를 정의하고, + 연산자를 오버로딩하여 두 복소수를 더하는 예제입니다.

#include <iostream>

class Complex {
private:
    double real;
    double imag;

public:
    // 생성자
    Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}

    // + 연산자 오버로딩 (멤버 함수)
    Complex operator+(const Complex& other) const {
        return Complex(real + other.real, imag + other.imag);
    }

    // 출력용 함수
    void display() const {
        std::cout << "(" << real << ", " << imag << ")" << std::endl;
    }
};

int main() {
    Complex c1(1.0, 2.0);
    Complex c2(3.0, 4.0);

    Complex c3 = c1 + c2; // + 연산자 사용

    std::cout << "c1: ";
    c1.display();

    std::cout << "c2: ";
    c2.display();

    std::cout << "c3 (c1 + c2): ";
    c3.display();

    return 0;
}

출력 결과

c1: (1, 2)
c2: (3, 4)
c3 (c1 + c2): (4, 6)

예제: 비교 연산자 오버로딩 (==)

다음은 두 복소수가 같은지 비교하기 위해 == 연산자를 오버로딩하는 예제입니다.

#include <iostream>

class Complex {
private:
    double real;
    double imag;

public:
    Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}

    // == 연산자 오버로딩
    bool operator==(const Complex& other) const {
        return (real == other.real) && (imag == other.imag);
    }
};

int main() {
    Complex c1(1.0, 2.0);
    Complex c2(1.0, 2.0);
    Complex c3(3.0, 4.0);

    std::cout << std::boolalpha; // bool 값을 true/false로 출력
    std::cout << "c1 == c2: " << (c1 == c2) << std::endl;
    std::cout << "c1 == c3: " << (c1 == c3) << std::endl;

    return 0;
}

출력 결과

c1 == c2: true
c1 == c3: false

연산자 오버로딩의 규칙

  1. 기존 연산자의 우선순위는 변경할 수 없습니다.
  2. 연산자의 기본 의미를 유지해야 합니다. 예를 들어, +는 더하기 동작을 나타내야 합니다.
  3. 적절한 반환값을 사용해야 합니다. 예를 들어, 비교 연산자는 bool 값을 반환해야 합니다.

오버로딩하지 못하는 연산자

다음 연산자는 C++에서 오버로딩할 수 없습니다:

  • :: (범위 지정 연산자)
  • . (멤버 접근 연산자)
  • .* (멤버 포인터 연산자)
  • sizeof (크기 연산자)
  • typeid (타입 정보 연산자)

마치며

연산자 오버로딩은 객체 지향 프로그래밍의 강력한 기능 중 하나로, 사용자 정의 타입을 더욱 직관적이고 자연스럽게 사용할 수 있도록 합니다. 위 예제를 참고하여 다양한 연산자를 오버로딩해 보세요. 연산자 오버로딩을 올바르게 사용하면 코드의 가독성과 유지 보수성을 크게 향상시킬 수 있습니다.

반응형

'cpp' 카테고리의 다른 글

C++ 템플릿 - 제네릭 프로그래밍  (0) 2024.12.20
C++ 네임스페이스(namespace)  (0) 2024.12.20
C++ 상속과 다형성  (0) 2024.12.19
C++ 클래스와 객체  (0) 2024.12.19
C++ 동적 메모리 관리  (0) 2024.12.19