개인의 학습을 목적으로 정리한 글입니다. 이점 참고하고 읽어주세요 ;)
int, float 등의 자료형으로 선언한 변수를 더하거나 뺄 때 우리는 아무런 이상함 없이 +, - 등등의 산술 연산자를 사용합니다.
이는 int를 비롯한 자료형에 이미 산술 연산자가 설정이 되어있기 때문인데요,
오늘은 사용자 정의 자료형이라고 할 수 있는 클래스의 산술 연산자를 오버로딩하는 법을 정리해보겠습니다.
class Cents
{
private:
int m_cents;
public:
Cents(int cents = 0) { m_cents = cents; }
int getCents() const { return m_cents; }
int getCents() { return m_cents; }
};
여기 간단하게 돈을 입력받고 그 값을 리턴하는 Cents 클래스를 정의했습니다.
int main()
{
Cents cents1(6);
Cents cents2(8);
return 0;
}
main 함수에서 Cents 자료형 cents1과 cents2를 정의하고, 두 객체에 저장된 값을 더하고 싶을 때,
클래스에 산술 연산자를 만들지 않고 해결하려면 어떻게 해야 할까요?
void add(const Cents& c1, const Cents& c2, Cents& c_out)
{
c_out.getCents() = c1.getCents() + c2.getCents();
}
전역 함수로 위의 코드 블록과 같은 add함수를 만들고
Cents sum;
add(cents1, cents2, sum);
cout << sum.getCents() << endl;
main 함수에서 위의 코드블록과 같이 add함수를 호출해야 합니다.
int와 같은 사전에 정의된 자료형은 변수를 초기화하고, 직관적으로 +, - 등의 산술 연산자를 사용하면 되는데
사용자 정의 자료형은 산술연산자를 정의하지 않으면 단순한 덧셈 산술에서도 꽤 복잡한 과정을 거치게 됩니다.
이러한 문제? 는 클래스에서 산술 연산자를 정의하면 해결이 됩니다.
Cents operator +(const Cents& c1, const Cents& c2)
{
return c1.getCents() + c2.getCents();
}
위의 코드 블록이 Cents 클래스의 +산술 연산자를 정의한 코드입니다.
Cents는 출력 자료형, operator+ 를 함수의 이름 정도로 생각하면 되고, 마지막 괄호 안에 있는 부분은 일반 함수처럼 매개변수로 생각하면 됩니다.
이렇게 산술 연산자를 정의해주면 따로 함수를 호출해서 Cents 클래스의 멤버인 getCents()를 사용할 필요도 없이
cout << (cents1 + cents2).getCents() << endl;
Cents클래스의 객체들을 더하고 그 값에서 getCents()를 호출해주면 됩니다.
Cents클래스에서는 아직 출력 연산자를 오버 로딩하지 않아서 getCents()를 호출하지 않으면 출력 시에 오류가 발생하는데,
출력 연산자 오버 로딩은 바로 다음 포스팅에서 다루겠습니다!
class Cents
{
private:
int m_cents;
public:
Cents(int cents =0) { m_cents = cents; }
int getCents() const { return m_cents; }
int& getCents() { return m_cents; }
friend Cents operator +(const Cents& c1, const Cents& c2)
{
return c1.m_cents + c2.m_cents;
}
};
처음에 보여드린 산술 연산자 정의 함수는 클래스 바깥에서 선언했다면,
위의 코드 블록처럼 아예 클래스를 정의할 때 friend 함수를 통해 멤버로 가지고 있으면,
산술 연산자에서 c1.getCents()+c2.getCent() 처럼 getCents()를 호출할 필요 없이
바로 private 멤버인 m_cents에 접근할 수 있습니다.
Cents operator +(const Cents& c1)
{
return (this->m_cents + c1.m_cents);
}
클래스 내에서 friend함수 말고 그냥 멤버로도 산술 연산자를 구현할 수 있습니다.
friend 함수 선언과 다른 점은,
그냥 멤버 함수로 사용할 경우에 매개변수를 2개 넣게 되면 컴파일러에서 이를 받아주지 않기 때문에
매개변수는 한 개로 설정하고, return 값을 더할 때에는
1. 하나는 this포인터를 사용하여 가져온 m_cents 2. 나머지는 매개변수로 받은 c1의 m_cents
이렇게 1번과 2번을 더하는 식으로 구현해야 합니다!
주의하실 점은
사용자 정의 자료형에서 산술 연산자를 설정할 때 더하기(+), 빼기(-), 곱하기(*) 등의 기본 연산자는 등록할 수 있는데,
삼항 연산자(? :), 범위 연산자(:) 등 등록? 할 수 없는 연산자도 존재한다고 합니다. 이는 제가 여기에 모두 나열할 수 없어서 필요하실 때 직접 찾아보시는 편이 좋을 것 같아요.
=, [], (), ->이렇게 4개의 연산자는 외부에 선언하면 안 되고 꼭 클래스 안에 멤버로 정의를 하셔야 한다고 해요
그리고 사용자 정의 자료형에서의 산술 연산자라고 하더라도, 산술 연산자의 우선순위는 변하지 않아서(예를 들면 곱하기(*)가 덧셈(+)보다 우선), 이점 역시 주의하시면서 프로그램을 짜셔야 합니다!
'Information Technology > C++' 카테고리의 다른 글
[C++] 단항 연산자 오버로딩 (0) | 2019.11.16 |
---|---|
[C++] 입출력 연산자 오버로딩 (0) | 2019.11.15 |
[C++] std::move(2) (0) | 2019.11.15 |
[C++] std::move(1) (0) | 2019.11.15 |
[C++] 이동 생성자와 이동 대입 (0) | 2019.11.15 |