C++ Chapter 9.5 : 비교 연산자 오버로딩

Date:     Updated:

카테고리:

태그:

인프런에 있는 홍정모 교수님의 홍정모의 따라 하며 배우는 C++ 강의를 듣고 정리한 필기입니다. 😀
🌜 [홍정모의 따라 하며 배우는 C++]강의 들으러 가기!


chapter 9. 연산자 오버로딩 : 비교 연산자 오버로딩

비교 연산자 : ==, !=, >, >=

추가적인 설명은 이전 포스트인 9.1 연산자 오버로딩 시작하기 참고하기

비교 연산자 오버로딩은 원래대로처럼 bool 타입을 리턴하도록 구현하는 것을 권장한다.

  • == : 객체끼리 같은지를 비교할 때 오버로딩
    • 오버로딩 안하고 객체 == 객체 해버리면 주소가 같냐, 즉 동일한 객체인가냐에 대한 결과를 얻는다.
    • 동일한 객체가 아니더라도 어떤 멤버 변수 값이 같으면 같은 객체라고 하고 싶다거나 그러면 == 연산자를 오버로딩 하면 된다!
  • != : 객체끼리 다른지를 비교할 때 오버로딩
  • >, >= : 객체의 크기를 비교할 때 오버로딩

🔔 전역 함수로 구현하기

#include <iostream>
using namespace std;

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 std::ostream& operator << (std::ostream &out, const Cents &cents)
	{
		out << cents.m_cents;
		return out;
	}

	friend bool operator == (const Cents &c1, const Cents &c2)
	{
		return c1.m_cents == c2.m_cents;
	}
};

int main()
{
	Cents cents1(6);
	Cents cents2(6);

	if (cents1 == cents2)
		cout << "Equal " << endl;
	return 0;
}
  • == 연산자를 오버로딩 하였다.
    • 피연산자가 2개 필요한데 전역 함수로 구현했으므로 Cents 타입의 객체 2개를 인수로 받는다.
    • 두 객체의 m_cents 멤버 값이 같으면 true를 리턴한다.
  • cents1 == cents2
    • 실제로 두 객체가 동일한 객체는 아니지만
      • ==연산자 오버로딩에 의하여 두 멤버 변수의 값이 같으므로 true를 리턴한다.


🔔 멤버 함수로 구현하기

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

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; }

	bool operator < (const Cents &c2)
	{
		return this->m_cents < c2.m_cents;
	}

	bool operator == (const Cents &c2)
	{
		return this->m_cents == c2.m_cents;
	}

	friend std::ostream& operator << (std::ostream &out, const Cents &cents)
	{
		out << cents.m_cents;
		return out;
	}
};
  • < 연산자를 오버로딩 하였다.
    • 피연산자가 2개 필요한데 멤버 함수로 구현했으므로 Cents 타입의 객체 1개를 인수로 받는다.
      • 나머지 하나는 자기 자신이다
        • 멤버를 호출하는 왼쪽 피연산자
    • 자기 자신의 멤버 값 (this->m_cents)과 인수로 받은 c2 객체의 c2.m_cents 멤버 값이 같으면 true를 리턴한다.
  • cents1 < cents2
    • cents1가 멤버 함수를 호출하여 cents2를 인수로 넘긴다.
    • 실제로 두 객체가 동일한 객체는 아니지만
      • ==연산자 오버로딩에 의하여 두 멤버 변수의 값이 같으므로 true를 리턴한다.

객체들을 담은 벡터 정렬하기

크기 비교가 가능해야 정렬을 할 수 있다.

  • 객체들을 담는 벡터 컨테이너를 정렬시키려면 크기 비교에 대한 기준이 있어야 한다.
    • 객체끼리는 크기 비교의 기준이 없기 때문에 비교 연산자를 오버로딩 해주어야 한다.
int main()
{
	vector<Cents> arr(10);

	for (unsigned i = 0; i < 10; ++i)
		arr[i].getCents() = i;

	std::random_shuffle(begin(arr), end(arr)); 
	
	for (auto &e : arr)
		cout << e << " ";
	cout << endl;

	std::sort(begin(arr), end(arr));

	for (auto &e : arr)
		cout << e << " ";

	return 0;
}
  • vector<Cents> arr(10);
    • Cents 타입의 객체를 10개 넣을 수 있는 벡터 arr 정의
  • for문의 arr[i].getCents() = i;
    • 이 때의 getCents는 int& getCents()이다.
      • 참조 타입으로 리턴하기 때문에 L-value로서 대입할 수 있다.
      • 각 원소(객체)의 m_data 멤버 변수에 i 값을 대입해준다.
        • 여기까지 하면 0 1 2 3 4 5 6 7 8 9 이렇게 각각 객체의 m_data 에 들어간다.
  • std::random_shuffle(begin(arr), end(arr));
    • 벡터 원소들을 랜덤하게 섞는다.
    • 이제 이걸 정렬해보자.
  • std::sort(begin(arr), end(arr));
    • 벡터 원소들 정렬
    • <, = 비교 연산자 오버로딩을 해주지 않으면 객체들의 크기를 비교할 기준이 없기 때문에 에러가 난다. 정렬 못 함!

오름차순 정렬

bool operator < (const Cents &c2)
{
	return this->m_cents < c2.m_cents;
}
  • < 이면 True
  • >= 이면 False
  • 그러므로 이렇게 오버로딩한 후 정렬시키면 오름차순 정렬 된다.

내림차순 정렬

bool operator < (const Cents &c2)
{
	return this->m_cents > c2.m_cents;
}
  • > 이면 True
  • <= 이면 False
  • 그러므로 이렇게 오버로딩한 후 정렬시키면 내림차순 정렬 된다.

크기 비교 연산자는 <만 오버로딩이 가능하다. >를 오버로딩 하고 싶다면 <을 오버로딩 한 후 내용을 >면 True를 리턴하게끔 구현하면 된다.



🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

맨 위로 이동하기


Cpp 카테고리 내 다른 글 보러가기

댓글 남기기