C++ 전역 연산자 오버로딩

tktj12·2023년 7월 2일
0

매력적이고 편리한 기능


class Matrix {
private:
	int element[2][2] = { 0, };
public:
	Matrix() {}

	Matrix operator*(int n) const {
		Matrix tp = *this;
		for (int i = 0; i < 2; ++i)
			for (int j = 0; j < 2; ++j)
				tp.element[i][j] *= n;
		return tp;
	}
}mat;

  위 같이 class 내에 연산자를 오버로딩 했을 때, mat * 1처럼 Matrix 객체가 * 연산 왼쪽에 오는 경우는 정상 동작 하지만, 1 * mat처럼 오른쪽에 오는 경우는 컴파일 에러가 발생한다.

  이 경우 전역으로 연산자를 오버로딩하여 처리할 수 있다.

class Matrix {
private:
	int element[2][2] = { 0, };
public:
...
	friend Matrix operator*(int, const Matrix&);
} mat;

Matrix operator*(int n, const Matrix& m) {
	Matrix tp = m;
	for (int i = 0; i < 2; ++i)
		for (int j = 0; j < 2; ++j)
			tp.element[i][j] *= n;
	return tp;
}

int main() {
...

  전역으로 오버로딩된 연산자는 위와 같이 연산의 왼쪽과 오른쪽에 대한 매개변수가 모두 필요하다.
  또한 접근하려는 요소는 Matrix 객체의 private 영역에 있기 때문에 friend 키워드를 사용해서 private에 접근할 수 있도록 해주어야 한다.

  그런데 다음과 같이 friend만 써주면 굳이 class 밖에 정의할 필요는 없다.

class Matrix {
private:
	int element[2][2] = { 0, };
public:
...
	friend Matrix operator*(int n, const Matrix& m) {
    	Matrix tp = m;
		for (int i = 0; i < 2; ++i)
			for (int j = 0; j < 2; ++j)
				tp.element[i][j] *= n;
		return tp;
    }
} mat;

그렇다고 멤버 함수처럼 되는 건 아니다. class 바깥에 전역으로 선언됐다고 봐야한다.



  • >> , <<에 대한 전역 연산자 오버로딩을 이용해 입, 출력을 간단한 모습으로 만들 수도 있다.
include <iostream>
using namespace std;

class Matrix {
private:
	int element[2][2] = { 0, };
public:
...
	friend istream& operator>>(istream& in, Matrix& m)
	{
		for (int i = 0; i < 2; ++i)
			for (int j = 0; j < 2; ++j)
				in >> m.element[i][j];
		return in;
	}

	friend ostream& operator<<(ostream& out, Matrix& m)
	{
		for (int i = 0; i < 2; ++i) {
			for (int j = 0; j < 2; ++j)
				out << m.element[i][j] << ' ';
			out << endl;
		}
		return out;
	}
} mat;

int main() {
	cin >> mat;
	cout << mat;
    
    return 0;
}

  반환형이 std::istream&, std::ostream&인 이유는 연속적으로 >> , << 연산을 할 수 있기 때문이다.

profile
C++, 알고리즘 공부

0개의 댓글