1. 연산자 재정의 기본 개념
#include <iostream>
class Point {
int x;
int y;
public:
Point( int a = 0, int b = 0 ) : x(a), y(b) {}
};
int main() {
int n = 1 + 2; // 3
Point p1(1, 1);
Point p2(2, 2);
Point p3 = p1 + p2; // ?
// operator+(p1, p2) -> operator+(Point, Point)
}
① +, -, *, 등의 연산자도 함수로 만들 수 있다.
=> operator+, operator-, operator*
2. a + b 를 컴파일러가 해석하는 방법
① a, b가 모두 primitive type (int, double 등) 인 경우
=> 일반적인 덧셈을 수행한다.
② a, b중 한 개라도 사용자 정의 타입이 있는 경우
=> operator+ 함수를 찾게 된다.
=> 방법1. 멤버 함수 검색
▶ a.operator+(b)
=> 방법2. 멤버가 아닌 일반 함수 검색
▶ operator+(a, b)
3. 멤버가 아닌 일반 함수로 구현하는 operator+
#include <iostream>
class Point {
int x;
int y;
public:
Point( int a = 0, int b = 0 ) : x(a), y(b) {}
void print() const {
std::cout << x << ", " << y << std::endl;
}
friend Point operator+(const Point& p1, const Point& p2);
};
Point operator+(const Point& p1, const Point& p2) {
Point temp;
temp.x = p1.x + p2.x;
temp.y = p1.y + p2.y;
return temp;
}
int main() {
Point p1(1, 1);
Point p2(2, 2);
Point p3 = p1 + p2; // operator+(p1, p2)
p3.print();
}
① +는 이항 연산자 이므로 인자가 2개 이어야 한다.
② 타입의 크기가 큰 경우 call by value보다는 const 참조가 좋다.
③ friend 함수로 만드는 경우가 많다.
4. 멤버 함수로 구현하는 operator+
#include <iostream>
class Point {
int x;
int y;
public:
Point( int a = 0, int b = 0 ) : x(a), y(b) {}
void print() const {
std::cout << x << ", " << y << std::endl;
}
// 멤버로 만드는 operator+
Point operator+( const Point& p ) {
Point temp;
temp.x = p.x + x;
temp.y = p.y + y;
return temp;
}
};
int main() {
Point p1(1, 1);
Point p2(2, 2);
Point p3 = p1 + p2; // p1.operator+(p2)
p3.print();
}
① +는 이항 연산자 이지만 인자가 1개 이어야 한다.
5. 멤버 함수 vs 멤버가 아닌 함수
#include <iostream>
class Point {
int x;
int y;
public:
Point( int a = 0, int b = 0 ) : x(a), y(b) {}
void print() const {
std::cout << x << ", " << y << std::endl;
}
// 멤버로 만드는 operator+
Point operator+( const Point& p ) {
std::cout << "member" << std::endl;
Point temp;
temp.x = p.x + x;
temp.y = p.y + y;
return temp;
}
friend Point operator+(const Point& p1, const Point& p2);
};
// 일반 함수로 구현
Point operator+(const Point& p1, const Point& p2) {
std::cout << "non member" << std::endl;
Point temp;
temp.x = p1.x + p2.x;
temp.y = p1.y + p2.y;
return temp;
}
int main() {
Point p1(1, 1);
Point p2(2, 2);
Point p3 = p1 + p2; // 1. p1.operator+(p2)
// 2. operator+(p1, p2)
p3.print();
}
실행결과
member
3, 3
① operator+ 함수의 인자의 개수
=> 멤버 함수 : 1개
=> 멤버가 아닌 함수 : 2개
② 멤버와 멤버가 아닌 함수를 동시에 제공하면
=> 멤버함수가 우선 시 된다.
int main() {
Point p1(1, 1);
Point p2(2, 2);
Point p3 = p1 + p2; // 1. p1.operator+(p2)
// 2. operator+(p1, p2)
p1 + 1; // 1. p1.operator+(int)
// 2. operator+(Point, int)
1 + p1; // 1. 1.operator+(Point) - 만들 수 없다.
// 2. operator+(int, Point) - 만들 수 있다.
}
③ a + b에서 첫 번째 인자인 a의 타입이
=> user type이면
▶ 멤버 함수와 멤버가 아닌 함수 모두 사용가능
=> user type이 아니면
▶ 멤버가 아닌 일반 함수로만 만들 수 있다.
④ 멤버 함수가 좋을까 ? 멤버가 아닌 함수가 좋을까 ?
=> 개발자들마다 의견이 다름...
6. operator+ 함수를 호출하는 방법
int main() {
Point p1(1, 1);
Point p2(2, 2);
Point p3 = p1 + p2; // 1. 컴파일러에 의해
operator+(p1, p2); // 2. 일반 함수로
p1.operator+(p2); // 3. 멤버 함수로
}
① 컴파일러에 의해
=> Point p3 = p1 + p2;
=> 멤버 함수 우선
② 일반 함수로
=> operator+(p1, p2);
③ 멤버 함수로
=> p1.operator+(p2);
'프로그래밍 > C++' 카테고리의 다른 글
[C++] 연산자 재정의 주의 사항 (0) | 2019.12.14 |
---|---|
[C++] 다중 상속 (multiple inheritance) (0) | 2019.12.03 |
[C++] RTTI (Run Time Type Information) (0) | 2019.12.02 |
[C++] 인터페이스 (interface) (0) | 2019.12.01 |
[C++] 추상 클래스 (abstract class) (0) | 2019.11.30 |