모든 내용은 [윤성우 저, "열혈 C++ 프로그래밍", 오렌지미디어] 를 기반으로 제 나름대로 이해하여 정리한 것입니다. 다소 부정확한 내용이 있을수도 있으니 이를 유념하고 봐주세요!
# 연산자 오버로딩
- 객체도 완벽히 기본 자료형 데이터처럼 취급하게 할 수 있음
- 'operator' 키워드 + '연산자' => 연산자를 이용한 함수의 호출도 허용
- 연산자 오버로딩한 함수도 const 선언이 가능
# 연산자 오버로딩 방법
1) 멤버함수에 의한 방법
class Point
{
private:
int xpos,ypos;
public:
...
Point operator+(const Point &ref)
{
Point pos(xpos+ref.xpos,ypos+ref.ypos);
return pos;
}
};
2) 전역함수에 의한 방법 : friend 선언 이용 또는 Get(), Set() 멤버함수 이용 이 동반됨
class Point
{
private:
int xpos,ypos;
public:
...
freind Point operator+(const Point &pos1, const Point &pos2);
/*
이 함수에 대해 friend를 선언하여
이 함수가 Point 클래스의 private 변수에 직접접근할 수 있게 함
*/
};
Point operator+(const Point &pos1, const Point &pos2)
{
Point pos(pos1.xpos+pos2.xpos,pos1.ypos+pos2.ypos)
return pos;
}
=> 동일한 자료형을 대상으로 두가지 방법으로 연산자 오버로딩을 할 경우,
멤버함수에 의한 방법이 우선시되어 호출되나, 가급적 이런 경우가 있게 하지는 말자.
# 객체지향에는 전역이라는 개념이 존재하지 않는다.
그러나, C++은 전역에 대한 개념이 여전히 존재하는데(C를 포함하고 있기 때문)
특별한 경우 아니면 쓰지 말자.
# 멤버함수 기반으로만 오버로딩이 가능한 연산자
=(대입연산자), ()(함수호출 연산자), [](배열 접근 연산자), ->(멤버 접근을 위한 포인터 연산자)
# 연산자 오버로딩 하는데 있어서의 주의사항
1) 본래의 의도를 벗어난 형태의 연산자 오버로딩은 좋지 않다.
2) 연산자의 우선순위와 결합성은 바뀌지 않는다.
3) 매개변수의 디폴트 값 설정이 불가능하다.
4) 연산자의 순수 기능까지 빼앗을 수는 없다.
# 증감연산자 오버로딩
++, --
# 전위연산 오버로딩시에는 참조값을 반환하게끔 오버로딩하자.
class Point
{
private:
int xpos,ypos;
public:
...
Point& operator++()
{
xpos+=1
ypos+=1
return *this;
}
friend Point& operator--(Point &ref);
};
Point& operator--(Point &ref)
{
ref.xpos-=1;
ref.ypos-=1;
return ref;
}
# 후위연산 오버로딩임을 표현하고 싶으면 (int)를 추가하고,
후위연산은 const 객체를 반환하게끔 오버로딩하자.
class Point
{
private:
int xpos,ypos;
public:
...
const Point operator++(int)
{
const Point retobj(xpos, ypos); // const Point retobj(*this);
xpos+=1
ypos+=1
return retobj;
}
friend const Point operator--(Point &ref, int);
};
const Point operator--(Point &ref, int)
{
const Point retobj(ref);
ref.xpos-=1;
ref.ypos-=1;
return retobj;
}
# 연산자 오버로딩에서의 교환법칙 해결
- 멤버함수 형태로 오버로딩하면, 오버로딩된 멤버함수가 정의된 클래스의 객체가
오버로딩된 연산자의 왼편에 반드시 와야하는 제약이 생긴다.
- 이러한 제약을 해결하기 위해
1) 전역함수의 형태로 오버로딩
2) 멤버함수 + 전역함수 형태를 동시에 이용
class Point
{
private:
int xpos,ypos;
public:
Point operator*(int times) // 멤버함수 오버로딩
{
Point pos(xpos*times,ypos*times)
return pos;
}
friend Point operator*(int times, Point &ref);
};
Point operator*(int times, Point &ref) // 전역함수 오버로딩 안에서 멤버함수 오버로딩을 이용
{
return ref*times;
}
# << 연산자 오버로딩
1) cout은 ostream 클래스의 객체이다.
2) ostream은 이름공간 std 안에 선언되어 있으며,
이의 사용을 위해서는 헤더파일 <iostream>을 포함해야 한다.
# >> 연산자 오버로딩
1) cin은 istream 클래스의 객체이다.
2) istream은 이름공간 std 안에 선언되어 있으며,
이의 사용을 위해서는 헤더파일 <iostream>을 포함해야 한다.
* << 연산자나 >> 연산자 오버로딩에 있어서
1) 멤버함수 오버로딩을 선택한다면 cout, cin 객체의 클래스 안에
멤버함수를 추가하여 오버로딩을 해야하므로 결국 ostream 클래스를 정정해야 한다.
2) 따라서, 전역함수에 의한 방법을 선택하자.
[출처] : 윤성우 저, "열혈 C++ 프로그래밍", 오렌지미디어
'Programming > 열혈 C++ 프로그래밍(저자 윤성우)' 카테고리의 다른 글
Ch 12. String 클래스의 디자인 (0) | 2020.08.17 |
---|---|
Ch 11. 연산자 오버로딩 2 (0) | 2020.08.17 |
Ch 07-09. 상속의 이해, 상속의 다형성, 가상(Virtual)의 원리와 다중상속 (0) | 2020.08.17 |
Ch 06. friend와 static 그리고 const (0) | 2020.08.17 |
Ch 05. 복사 생성자(Copy Constructor) (0) | 2020.08.17 |