연산자 오버로딩 (Operator Overloading)

  • 기본으로 제공하는 연산자를 함수처럼 매개변수의 개수나 자료형에 따라 오버로딩하여 사용하는 것.

  • +, -, *, / 등의 기본 이항 연산자부터 =, ->, * 등의 연산자까지 대부분의 연산자에 대해 오버로딩이 가능.

  • 단, 멤버 참조 연산자(operator.)와 조건 연산자(operator?:), 그리고 범위 결정 연산자(operator::) 및 멤버 포인트 연산자(operator.*)는 오버로딩이 불가능.

  • 객체를 매개변수로 받을 때, 복사에 의한 오버헤드를 줄이고 원본 객체의 안전성을 유지하기 위해 반드시 const reference 로 넘겨야 함.

#include <iostream>
using namespace std;


class WorkHour {
private:
    int workHour;
public:
    WorkHour(int w) : workHour(w) { }
    
    void printWorkHour() {
        cout << "WorkHour: " << workHour << endl;
    }
    
    WorkHour add(const WorkHour& work) {
        WorkHour wh(this->workHour + work.workHour);
        return wh;
    }
    
    WorkHour operator+(const WorkHour& rhs) {
        WorkHour wh(this->workHour + rhs.workHour);
        return wh;
    }
};


int main() {
    WorkHour worker1(2);
    WorkHour worker2(3);
    // WorkHour worker3 = worker1.add(worker2); // new object
    WorkHour worker3 = worker1 + worker2; // same as above
    worker3.printWorkHour(); // 5
    return 0;
}
  • 연산자 오버로딩 시, 객체를 매개변수로 받을 때 해당 객체 뿐만 아니라 객체 생성자의 매개변수들만 넘겼을 경우 객체를 자동으로 생성함.

int main() {
    WorkHour worker1(2);
    // WorkHour worker2(3);
    // WorkHour worker3 = worker1 + worker2;
    WorkHour worker3 = worker1 + 3; // same as above
    worker3.printWorkHour(); // 5
    return 0;
}
  • 단, 연산자의 좌측이 객체인 경우에만 위의 연산이 가능하며, 역으로 WorkHour worker3 = 3 + worker1; 는 "'WorkHour' 형식을 사용하는 전역 연산자가 없거나 허용되는 변환이 없습니다."라는 컴파일 오류를 일으킴.

  • 연산자의 좌우에서 객체가 아니더라도 동일하게 동작하려면 다음과 같은 friend 키워드를 사용해서 오버로딩 해야 함.

#include <iostream>
using namespace std;


class WorkHour {
private:
    int workHour;
public:
    WorkHour(int w) : workHour(w) { }

    void printWorkHour() {
        cout << "WorkHour: " << workHour << endl;
    }

    friend WorkHour operator+(const WorkHour& lhs,
                              const WorkHour& rhs);
};


WorkHour operator+(const WorkHour& lhs, const WorkHour& rhs) {
    WorkHour wh(lhs.workHour + rhs.workHour);
    cout << "operator+(lhs, rhs);" << endl;
    return wh;
}


int main() {
    WorkHour worker1(2);
    WorkHour worker2(3);
    WorkHour worker3 = 3 + worker1;
    WorkHour worker4 = worker2 + 4;
    worker3.printWorkHour(); // 5
    worker4.printWorkHour(); // 7
    return 0;
}

/*
operator+(lhs, rhs);
operator+(lhs, rhs);
WorkHour: 5
WorkHour: 7
*/
  • 연산자 오버로딩 시 호출 우선순위.

#include <iostream>
using namespace std;


class WorkHour {
private:
    int workHour;
public:
    WorkHour(int w) : workHour(w) { }

    void printWorkHour() {
        cout << "WorkHour: " << workHour << endl;
    }

    WorkHour operator+(const WorkHour& rhs);
    friend WorkHour operator+(const WorkHour& lhs,
                              const WorkHour& rhs);
};


WorkHour WorkHour::operator+(const WorkHour& rhs) {
    WorkHour wh(this->workHour + rhs.workHour);
    cout << "operator+(rhs);" << endl;
    return wh;
}


WorkHour operator+(const WorkHour& lhs, const WorkHour& rhs) {
    WorkHour wh(lhs.workHour + rhs.workHour);
    cout << "operator+(lhs, rhs);" << endl;
    return wh;
}


int main() {
    WorkHour worker1(2);
    WorkHour worker2(3);
    WorkHour worker3 = 3 + worker1;
    WorkHour worker4 = worker2 + 4;
    worker3.printWorkHour(); // 5
    worker4.printWorkHour(); // 7
    return 0;
}

/*
operator+(lhs, rhs);
operator+(rhs);
WorkHour: 5
WorkHour: 7
 */

 

+ Recent posts