반응형

 

 

※ firend의 개념을 모른다면 다음 포스팅을 먼저 숙지할 것.

 

C++ friend

friend 선언 - 접근지시자에 관계없이 모든 멤버의 접근을 허용하는 선언이다. ※ 그렇기 때문에, 클래스의 friend 선언은 객체 지향의 정보 은닉 개념에 위배된다. - friend는 사용되는 클래스에서 선

srdeveloper.tistory.com

 

연산자 오버로딩

- 사용자 정의 자료형(클래스)에 연산자를 재정의한다.

- operator 키워드와 연산자를 묶어서 함수이름을 정의하면 연산자 오버로딩이 이루어진다.

  • 예 : class operator+(const class& ref)

- 연산자 오버로딩은 멤버함수에 의한 연산자 오버로딩, 전역함수에 의한 연산자 오버로딩이 있다.

  • 멤버함수 연산자 오버로딩 : class.operator+(class)
  • 전역함수 연산자 오버로딩 : class.operator+(class, class)

 

 

  • 멤버함수, 전역함수 연산자 오버로딩 예제
#include <iostream>
using namespace std;

class OverloadingOP
{
private:
    int m_iNum1, m_iNum2;

public:
    OverloadingOP(int n1 = 0, int n2 = 0) : m_iNum1(n1), m_iNum2(n2) { }
    void ShowMember()
    {
        cout << m_iNum1 << " / " << m_iNum2 << endl;
    }
    //멤버함수 연산자 오버로딩
    OverloadingOP operator+(const OverloadingOP& ref)
    {
        return OverloadingOP(m_iNum1 + ref.m_iNum1, m_iNum2 + ref.m_iNum2);
    }
    //전역함수 연산자 오버로딩
    friend OverloadingOP operator+(const OverloadingOP& ref1, const OverloadingOP& ref2);
};

OverloadingOP operator+(const OverloadingOP& ref1, const OverloadingOP& ref2)
{
    return OverloadingOP(ref1.m_iNum1 + ref2.m_iNum1, ref1.m_iNum2 + ref2.m_iNum2);
}

void main()
{
    OverloadingOP op1(3, 4);
    OverloadingOP op2(10, 10);
    OverloadingOP op3 = op1 + op2;
    
    op3.ShowMember();
    
    //결과 : 13 / 14
}

 - 전역함수로 연산자 오버로딩을 할 시, 해당 클래스의 멤버에 접근할수 있어야하므로 friend 선언을 해준다. (friend 키워드의 적절한 사용예)

 

 

 

연산자 오버로딩 주의점

- 연산자 오버로딩이 멤버함수, 전역함수로 둘 다 존재할 경우, 멤버함수로 오버로딩된 함수가 우선시되어 호출되므로, 특별한 경우가 아니라면 멤버함수 기반으로 연산자 오버로딩을 하는것이 좋다.

- 매개변수의 디폴트값 설정이 불가능하다.

- 연산자의 우선순위와 결합성은 바뀌지 않는다. (연산자가 지니는 우선순위와 결합성은 그대로 따라간다.)

 

 

 

단항연산자의 오버로딩

- 단항연산자(++, --)는 매개변수가 없다.

  • 멤버함수 연산자 오버로딩 : class.operator++()
  • 전역함수 연산자 오버로딩 : operator++(class)

- 단항연산자의 전위, 후위 구분은 int로 구분한다.

  • 전위 : operator++()
  • 후위 : operator++(int)

  ※ int는 데이터를 전달하는 뜻이 아닌, 단순히 전위와 후위를 구분하기 위해서 사용하는것이다.

 

 

  • 단항연산자 오버로딩 예제
#include <iostream>
using namespace std;

class OverloadingOP
{
private:
    int m_iNum1, m_iNum2;

public:
    OverloadingOP(int n1 = 0, int n2 = 0) : m_iNum1(n1), m_iNum2(n2) { }
    void ShowMember()
    {
        cout << m_iNum1 << " / " << m_iNum2 << endl;
    }
    //전위
    OverloadingOP& operator++()
    {
        m_iNum1++;
        m_iNum2++;
        return *this;
    }
    //후위
    const OverloadingOP operator++(int)
    {
        const OverloadingOP returnValue(m_iNum1, m_iNum2);
        m_iNum1++;
        m_iNum2++;
        return returnValue;
    }
};

void main()
{
    OverloadingOP op(5, 10);
    (++op).ShowMember();
    (op++).ShowMember();
    
    //결과
    //6 / 11
    //6 / 11
}

 - C++가 ++(++obj)의 연산은 허용하되 (obj++)++를 허용하지 않는 연산특성을 가지고 있으므로 후위증감연산자의 경우 반환값을 const로 지정한다.

 

 

 

 

단항연산자의 오버로딩 시 교환법칙의 문제 해결하기

- 교환법칙 : A + B와 B + A의 결과가 서로 같음을 뜻한다. 즉, 연산자를 중심으로 한 피연산자의 위치는 연산 결과값이 같다는 법칙이다. (곱셈, 덧셈 연산이 있음)

- 자료형이 다른 두 피연산자를 대상으로 연산을 해야하는 경우, 형 변환으로 하여 자료형을 맞춘 다음에 연산이 이루어져야한다.

- 연산자 오버로딩을 이용하면 위와 같은 규칙에 예외를 둘 수 있다.

 

 

  • 교환법칙 예외두기 예제
#include <iostream>
using namespace std;

class OverloadingOP
{
private:
    int n;

public:
    OverloadingOP(int x) : n(x){ }
    void ShowMemver()
    {
        cout << n << endl;
    }
    //이 오버로딩은 OverloadingOP * int만 허용한다.
    OverloadingOP operator*(int i)
    {
        return OverloadingOP(n * i);
    }
    //이 오버로딩은 int * OverloadingOP만 허용한다.
    friend OverloadingOP operator*(int i, OverloadingOP& ref);
};

OverloadingOP operator*(int i, OverloadingOP& ref)
{
    return OverloadingOP(ref.n * i);
    //or
    return ref * i;
}

void main()
{
    OverloadingOP op1(5);
    OverloadingOP op2 = op1 * 2;
    OverloadingOP op3 = 2 * op1;
    
    op2.ShowMemver();
    op3.ShowMemver();
    
    //결과
    //10
    //10
}

 - 멤버함수의 형태로 오버로딩을 하게되면, 멤버함수가 정의된 클래스의 객체가 오버로딩 된 연산자의 왼편에 있어야 컴파일이 가능해진다.

 - 우측에 클래스의 객체를 둔 연산이 필요할 때에는 전역함수의 형태로 오버로딩을 해야 컴파일이 가능해진다.

 

 


 

C++ 연산자 오버로딩 (대입, 인덱스 연산자)

※ 연산자 오버로딩 기본 개념 참고 C++ 연산자 오버로딩 ※ firend의 개념을 모른다면 다음 포스팅을 먼저 숙지할 것. C++ friend friend 선언 - 접근지시자에 관계없이 모든 멤버의 접근을 허용하는 선

srdeveloper.tistory.com

 

 

 

반응형

'Stack > C++' 카테고리의 다른 글

C++ 연산자 오버로딩 (대입, 인덱스 연산자)  (0) 2021.12.26
C++ 네임스페이스(namespace), using  (0) 2021.12.12
C++ friend  (0) 2021.12.05
C++ 다중상속  (0) 2021.11.22
C++ 멤버함수, 가상함수 동작원리  (0) 2021.11.17

+ Recent posts