본문 바로가기
Language/C++

[c++][씹어먹는 c++] 5 - 1. 연산자 오버로딩

by 담백로봇 2024. 4. 25.

출처: https://modoocode.com/202

 

씹어먹는 C++ - <5 - 1. 내가 만든 연산자 - 연산자 오버로딩>

모두의 코드 씹어먹는 C++ - <5 - 1. 내가 만든 연산자 - 연산자 오버로딩> 작성일 : 2013-08-25 이 글은 92920 번 읽혔습니다. 에 대해서 다룹니다. 안녕하세요 여러분! 지난 강좌에서 만들었던 MyString 을

modoocode.com


주요 키워드: 산술 연산자 오버로딩, 비교 연산자 오버로딩, 대입 연산자 오버로딩

 

산술 연산자 오버로딩

C++에서 산술 연산자를 오버로딩하는 것은 사용자 정의 클래스에 대해 산술 연산을 사용할 수 있도록 하는 중요한 기능.

 

 

왜 필요한거야
오버로딩은 함수나 연산자를 여러 가지 방식으로 사용할 수 있게 하는 기능. 이는 같은 이름의 함수나 연산자를 여러 형태로 정의할 수 있게 해주어 코드의 유연성을 높임. 이렇게 하면 다형성(Polymorphism)이 증가하여 코드가 간결하고 직관적. 오버로딩은 가독성과 유지 보수성을 향상시키고 표준 라이브러리와의 호환성을 강화.

 

 

일단 연산자 오버로딩을 사용하기 위해서는, 다음과 같이 오버로딩을 원하는 연산자 함수를 제작하면 됨.

(리턴 타입) operator(연산자) (연산자가 받는 인자)

(※ 참고적으로 위 방법 외에는 함수 이름으로 연산자를 절대 넣을 수 없음)

두 개의 복소수(Complex number)를 더하는 경우의 예제.

#include <iostream>

class Complex {
private:
    double real;
    double imaginary;

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

    // '+' 연산자 오버로딩
    Complex operator+(const Complex& other) const {
        return Complex(real + other.real, imaginary + other.imaginary);
    }

    // '-' 연산자 오버로딩
    Complex operator-(const Complex& other) const {
        return Complex(real - other.real, imaginary - other.imaginary);
    }

    // '*' 연산자 오버로딩
    Complex operator*(const Complex& other) const {
        double resultReal = real * other.real - imaginary * other.imaginary;
        double resultImaginary = real * other.imaginary + imaginary * other.real;
        return Complex(resultReal, resultImaginary);
    }

    // '/' 연산자 오버로딩
    Complex operator/(const Complex& other) const {
        double denominator = other.real * other.real + other.imaginary * other.imaginary;
        double resultReal = (real * other.real + imaginary * other.imaginary) / denominator;
        double resultImaginary = (imaginary * other.real - real * other.imaginary) / denominator;
        return Complex(resultReal, resultImaginary);
    }

    // 출력 연산자 오버로딩
    friend std::ostream& operator<<(std::ostream& os, const Complex& complex);
};

// 출력 연산자 오버로딩 구현
std::ostream& operator<<(std::ostream& os, const Complex& complex) {
    os << complex.real << " + " << complex.imaginary << "i";
    return os;
}

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

    Complex addition = c1 + c2;
    Complex subtraction = c1 - c2;
    Complex multiplication = c1 * c2;
    Complex division = c1 / c2;

    std::cout << "Addition: " << addition << std::endl;
    std::cout << "Subtraction: " << subtraction << std::endl;
    std::cout << "Multiplication: " << multiplication << std::endl;
    std::cout << "Division: " << division << std::endl;

    return 0;
}

위 코드에서는 Complex 클래스에 대해 +, -, *, / 연산자를 오버로딩하여 복소수 간의 덧셈, 뺄셈, 곱셈, 나눗셈을 수행할 수 있도록 작성. 코드 실행 시, 오버로딩된 연산자가 호출되어 해당 연산을 수행하고 그 결과를 출력.


비교 연산자 오버로딩

C++에서 비교 연산자 오버로딩을 사용하는 방법 및 예제.

cppCopy code
class MyClass {
public:
    // 비교 연산자 오버로딩
    bool operator==(const MyClass& other) const {
        // 비교 연산을 수행하고 결과를 반환
        // 예를 들어, 두 객체의 멤버 변수를 비교하여 같은지 여부를 판단
        return (this->memberVariable == other.memberVariable);
    }

    // 다른 비교 연산자들도 마찬가지로 오버로딩할 수 있습니다.
    bool operator!=(const MyClass& other) const {
        // 비교 연산을 수행하고 결과를 반환
        return !(*this == other); // == 연산자를 사용하여 반대의 결과를 반환
    }

    bool operator<(const MyClass& other) const {
        // 비교 연산을 수행하고 결과를 반환
    }
};

위의 코드에서 operator== 함수는 두 개의 MyClass 객체를 비교하는 데 사용. 이러한 비교 연산자는 클래스 내에서 멤버 함수로 정의되며, ==, !=, <, >, <=, >= 등과 같은 연산자를 오버로딩할 수 있음.

비교 연산 예제

cppCopy code
MyClass obj1(5);
MyClass obj2(5);
MyClass obj3(10);

if (obj1 == obj2) {
    // obj1과 obj2가 같은 경우
}

if (obj1 != obj3) {
    // obj1과 obj3가 다른 경우
}

if (obj1 < obj3) {
    // obj1이 obj3보다 작은 경우
}


대입 연산자 오버로딩

C++에서 대입 연산자(=)를 오버로딩하여 사용자가 정의한 클래스에 대해 사용자가 원하는 대입 동작을 지정할 수 있음. 대입 연산자는 객체의 멤버 변수 값을 다른 객체로 복사할 때 사용. 이를 통해 얕은 복사(shallow copy)나 깊은 복사(deep copy) 등의 특정 동작을 수행할 수 있다.

예를 들어, 문자열을 저장하는 String 클래스로 가정.

#include <iostream>
#include <cstring> // 문자열 처리 함수를 사용하기 위해 포함

class String {
private:
    char* buffer;

public:
    // 생성자
    String(const char* initial) {
        buffer = new char[strlen(initial) + 1];
        strcpy(buffer, initial);
    }

    // 소멸자
    ~String() {
        delete[] buffer;
    }

    // 대입 연산자 오버로딩
    String& operator=(const String& other) {
        // 자기 자신과의 대입을 처리
        if (this == &other)
            return *this;

        // 기존 버퍼 해제
        delete[] buffer;

        // 새로운 버퍼 할당 및 복사
        buffer = new char[strlen(other.buffer) + 1];
        strcpy(buffer, other.buffer);

        return *this;
    }

    // 문자열 출력 함수
    void print() const {
        std::cout << buffer << std::endl;
    }
};

int main() {
    String str1("Hello");
    String str2("World");

    std::cout << "Before assignment:" << std::endl;
    str1.print();
    str2.print();

    // 대입 연산자를 사용하여 str2를 str1에 할당
    str1 = str2;

    std::cout << "After assignment:" << std::endl;
    str1.print();
    str2.print();

    return 0;
}

위의 코드에서는 String 클래스에 대입 연산자를 오버로딩하여 깊은 복사를 수행하도록 구현됨. 이를 통해 객체 간의 문자열 복사가 안전하게 이루어 질 수 있음. 코드 실행 결과, str1이 str2에 할당된 결과가 출력!

댓글