강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

오원택님의 프로필 이미지
오원택

작성한 질문수

홍정모의 따라하며 배우는 C++

9.5 증감 연산자 오버로딩 하기

9.4 강 오버로딩에서 friend operator<와 멤버함수operator<

작성

·

403

0

강의에서 써주신 부분에서 friend를 쓰셨는데 bool operator<(const Cents& c2)를 통해 멤버함수로 바꿔주고 두개를 다 사용할때 어떤게 실행될까 했는데 bool operator<이 실행되더라구요? friend는 멤버함수 operat<이 없을때 실행되는거 같은데 혹시 이러한 우선순위에 대해서 찾아볼려고 하는데 혹시 키워드가 있는 내용인건가요?

#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;


class Cents {
private:
	int m_cents;
public:
	Cents(const int& input = 0)
		: m_cents(input)
	{}

	int getCents() const { return m_cents; }
	int& getCents() { return m_cents; }


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

	friend bool operator<(const Cents& c1, const Cents& c2) {
		cout << "friend인가?" << endl;
		return c1.m_cents < c2.m_cents;
	}

	bool operator<(const Cents& c2) {
		cout << "어떤게 실행되나?" << endl;
		return m_cents < c2.m_cents;
	}
	friend bool operator>(const Cents& c1, const Cents& c2) {
		cout << "friend인가?" << endl;
		return c1.m_cents > c2.m_cents;
	}
	friend std::ostream& operator<<(std::ostream &out, const Cents& cents) { //멤버함수로 안되나?
		out << cents.m_cents; // 한푼도 없을때 참이 나오도록 구현
		return out; // 하는 이유는 chaing할려는 것 이러면 cout<<Point<<... 이렇게 연속적으로 쓸수 있다.
	}

	friend std::istream& operator>>(std::istream& in, Cents &cents) {//입력을 받아 수행해야하므로 const 하면 안된다.
		in >> cents.m_cents;
		return in;
	}
};


int main() {
	vector<Cents> arr(20);
	for (int i = 0; i < 20; i++) {
		arr[i].getCents() = i;
	}
	std::random_shuffle(arr.begin(), arr.end());
	for (auto ele : arr)
		cout << ele << " ";
	cout << endl;

	std::sort(arr.begin(), arr.end());
	for (auto ele : arr)
		cout << ele << " ";
	cout << endl;
	return 0;
}

퀴즈

사용자 정의 타입에 대해 연산자 오버로딩을 하는 주된 목적은 무엇일까요?

코드 실행 속도를 빠르게 하기 위해

사용자 정의 타입을 내장 타입처럼 자연스럽게 사용하기 위해

객체의 메모리 관리를 자동화하기 위해

클래스의 상속 관계를 정의하기 위해

답변 4

1

오원택님의 프로필 이미지
오원택
질문자

단번에 이해는 안가지만 한번 찾아보면서 공부해보겠습니다. 감사합니다

1

오원택님의 프로필 이미지
오원택
질문자

이해가 잘 안되서 다시 질문드립니다. 올려주신 간단한 예시는 l value r value 개념이 아닌가요? test(a)같은경우에는 a라는 메모리를 차지하는 변수가 있어 l value이기에 test(int & a)로 들어가는 반면 test(3)은 3이 리터럴이고 r-value이기에 test(int &a)로는 못가고 test(const int& a)에서 const T& 같은 경우 상수나 double변수를 int파라미터에 넣는 것같은 경우에 발생하는 narrow일 때 작동되도록 const int& 이 작동하는걸로 알고 있는데 제가 올린 내용인 l-value r-value와 관련된 내용인것인건가요?

제가 올린 예시코드에서는 vector를 통해 어쨋든 변수를 적용했을텐데 어째서 구별이 되는건지 조금 이해가 안됩니다. 예시처럼 변수이니까 우선 int &a처럼 const가 아닌것이 우선이 된다는 것인건가요?

0

안녕하세요?
l value 와 r value와는 관련이 없습니다. 헷갈릴 수 있게 적어드린 것 같군요.
아래의 코드가 좀 더 적절합니다. 마지막에 내리신 결론이 맞으며,구현하신 코드에서 const를 넣었다 뺐다 해보시면 좀 더 잘 이해하실 수 있을 것 같습니다.

#include <iostream>
using namespace std;

int test(int &a)
{
	cout << "non-const object." << endl;
	return 3;
}

int test(const int &a)
{
	cout << "const object." << endl;
	return 3;
}

int main() {
	int a;
	const int b=3;
	test(a);
	test(b);
}

0

class member 로서 operator를 정의하신 것처럼 선언하면 암시적으로 첫번째 parameter를 다음과 같은 형태로 받습니다.
bool operator>(Cents &c1, const Cents &c2) {...} // https://www.learncpp.com/cpp-tutorial/94-overloading-operators-using-member-functions/
결론은 두 operator는 구분이 됩니다. 때문에 const object를 넣으면 다르게 작동합니다. 모든 parameter에서 'const' keyword를 빼면 두 operator가 구분이 불가능하기 때문에 컴파일이 안되네요.

좀 더 간단한 비교로는 다음과 같은 것이 될 수 있겠군요.

#include <iostream>
using namespace std;

int test(int &a)
{
	cout << "non-const object." << endl;
	return 3;
}

int test(const int &a)
{
	cout << "const object." << endl;
	return 3;
}

int main() {
	int a;
	test(a);
	test(3);
}
오원택님의 프로필 이미지
오원택

작성한 질문수

질문하기