본문 바로가기

C++/C++ 문법

C++ 연산자 오버로딩과 프렌드

728x90

기본적인 연산자 오버로딩

C++은 +, == 와 같은 연산자를 오버로딩할 수 있다.

 

#include "iostream"

class Point {
public:
  Point(int _x, int _y) {
    this->x = _x;
    this->y = _y;
  }
  Point() {
    Point(0, 0);
  }

  Point operator + (const Point &o) {
    Point ret;
    ret.x = o.x + (*this).x;
    ret.y = o.y + (*this).y;
    return ret;
  }

  bool operator == (const Point &o) {
    return (*this).x == o.x and (*this).y == o.y;
  }

private:
  int x;
  int y;
};

int main() {
  Point p1(1, 2);
  Point p2(1, 2);
  auto is_same = p1 == p2;
  std::cout << is_same;
}

 

// output
1

 

이런식으로 클래스의 연산자를 정의해줄 수 있다.

프렌드

그런데 만약 위에 만든 Point 클래스로 이런걸 하고 싶다면 어떻게 할까?

 

Point p1;

p1 = 2 * p1;

 

아쉽게도 클래스 내의 연산자 오버로딩으로는 위와 같은 연산을 할 수 없다.

 

왜냐하면 Point 객체끼리 더할 때는 p1.operator+(p2)와 같이 해석되지만 위와 같이 객체가 피연산자로 올 때는 이를 위한 전역 함수가 필요하기 때문이다.

 

같은 이유로 출력 연산자도 그냥은 오버로딩 할 수 없다.

 

std::cout << p1; // <--???

 

위와 같은 연산을 하기 위해서 필요한 것이 프렌드이다.

 

프렌드는 해당 클래스의 private 멤버에 접근할 수 있게 해주는 키워드이다. 프렌드는 여러 사용법이 있지만 연산자 오버로딩에서는 다음과 같이 활용할 수 있다.

 

#include "iostream"

class Point {
public:
  Point(int _x, int _y) {
    this->x = _x;
    this->y = _y;
  }
  Point() {
    Point(0, 0);
  }

  Point operator + (const Point &o) {
    Point ret;
    ret.x = o.x + (*this).x;
    ret.y = o.y + (*this).y;
    return ret;
  }

  bool operator == (const Point &o) {
    return (*this).x == o.x and (*this).y == o.y;
  }

  friend Point operator * (size_t factor, const Point &o);

  friend std::ostream& operator << (std::ostream& out, const Point &o);

private:
  int x;
  int y;
};

Point operator * (size_t factor, const Point &o) {
  return Point(o.x  * factor, o.y * factor);
}

std::ostream& operator << (std::ostream& out, const Point &o) {
  out << o.x << ", " << o.y;
  return out;
}

int main() {
  Point p1(1, 2);
  auto p3 = 2 * p1;
  std::cout << p3;
}

 

// output
2, 4

 

프렌드 함수를 선언해 private 멤버인 x와 y에 접근할 수 있도록 하고 전역 함수에서 두 연산자 오버로딩을 시행하여 private 멤버를 활용한 연산을 하는 것을 볼 수 있다.

728x90

'C++ > C++ 문법' 카테고리의 다른 글