매력적이고 편리한 기능
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&인 이유는 연속적으로 >>
, <<
연산을 할 수 있기 때문이다.